После проверки и до того, как INSERT проверяет, существует ли имя пользователя, с помощью mysqli (процедурный). Это работает:
//check if username already exists
include 'phpscript/connect.php'; //connect to your database
$sql = "SELECT username FROM users WHERE username = '$username'";
$result = $conn->query($sql);
if($result->num_rows > 0) {
$usernameErr = "username already taken"; //takes'em back to form
} else { // go on to INSERT new record
Для событий вы должны использовать EventToCommand в MVVM Light Toolkit. Используя это, вы можете привязать любое событие любого элемента пользовательского интерфейса к relaycommand. Проверьте его статью о EventToCommand в
Загрузите образец и посмотрите. Это великолепно. Тогда вам не понадобится какой-либо код. Пример выглядит следующим образом:
<Page x:Class="cubic.cats.Wpf.Views.SplashScreenView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="SplashScreenPage">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<cmd:EventToCommand Command="{Binding LoadedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<Label Content="This is test page" />
</Grid>
</Page>
и режим просмотра может быть таким
public class SplashScreenViewModel : ViewModelBase
{
public RelayCommand LoadedCommand
{
get;
private set;
}
/// <summary>
/// Initializes a new instance of the SplashScreenViewModel class.
/// </summary>
public SplashScreenViewModel()
{
LoadedCommand = new RelayCommand(() =>
{
string a = "put a break point here to see that it gets called after the view as been loaded";
});
}
}
, если вы хотите, чтобы модель представления имела EventArgs, вы можете просто установить PassEventArgsToCommand на true:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<cmd:EventToCommand PassEventArgsToCommand="True" Command="{Binding LoadedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
и модель вида будет похожа на
public class SplashScreenViewModel : ViewModelBase
{
public RelayCommand<MouseEventArgs> LoadedCommand
{
get;
private set;
}
/// <summary>
/// Initializes a new instance of the SplashScreenViewModel class.
/// </summary>
public SplashScreenViewModel()
{
LoadedCommand = new RelayCommand<MouseEventArgs>(e =>
{
var a = e.WhateverParameters....;
});
}
}
Следующее решение похоже на уже предоставленное и принятое, но оно использует не команду в модели представления для загрузки данных, а «нормальный метод». Я думаю, что команды больше подходят для действий пользователя (команды могут быть доступны и недоступны во время выполнения), поэтому используют обычный вызов метода, но также устанавливают триггер взаимодействия в представлении.
Я предлагаю это: создать класс модели представления. Создайте класс модели представления в xaml представления, создав его внутри свойства DataContext
.
Реализуйте метод для загрузки данных в вашу модель представления, например, LoadData
. Настройте представление так, чтобы этот метод вызывался при загрузке представления. Это делается с помощью триггера взаимодействия в вашем представлении, который связан с методом в модели представления (необходимы ссылки на «Microsoft.Expression.Interactions» и «System.Windows.Interactivity»):
View ( xaml):
<Window x:Class="MyWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test"
xmlns:viewModel="clr-namespace:ViewModels"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
>
<Window.DataContext>
<viewModel:ExampleViewModel/>
</Window.DataContext>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<ei:CallMethodAction TargetObject="{Binding}" MethodName="LoadData"/>
</i:EventTrigger>
</i:Interaction.Triggers>
Это вызовет метод LoadData
в ViewModel во время выполнения, когда загружено представление. Здесь вы загружаете свои данные.
public class ExampleViewModel
{
/// <summary>
/// Constructor.
/// </summary>
public ExampleViewModel()
{
// Do NOT do complex stuff here
}
public void LoadData()
{
// Make a call to the repository class here
// to set properties of your view model
}
Если метод в хранилище является асинхронным, вы также можете сделать метод LoadData
асинхронным, но это не требуется в каждом случае.
Кстати, вообще я бы не стал загружать данные в конструктор модели представления. В приведенном выше примере конструктор (без параметров) модели представления вызывается, когда дизайнер отображает ваше представление. Выполнение сложных вещей может привести к ошибкам в конструкторе при отображении вашего представления (по той же причине, по которой я не буду делать сложные вещи в конструкторе представлений).
В некоторых сценариях код в конструкторе моделей представлений может даже вызывать проблемы во время выполнения, когда выполняются конструкторы моделей представлений, устанавливать свойства модели представления, которые привязаны к элементам в представлении, пока объект представления не полностью завершен, создавая .
Я решил просто связать XAML, декларативно связанный с обработчиком события Loaded в программном коде View, который, в свою очередь, просто вызвал метод объекта ViewModel через корневой элемент View UserControl DataContext.
Это было довольно простое, прямое и чистое решение. Думаю, я надеялся найти способ связать событие Loaded с объектом ViewModel таким же декларативным способом, каким вы можете использовать ICommands в XAML.
Возможно, я дал Клинджеру официальный ответ, но он оставил комментарий на мой вопрос, а не ответ. Поэтому я, по крайней мере, дал ему один комментарий к нему.
У меня была такая же проблема при работе с сообщениями между родительским окном и дочерним окном. Просто измените порядок создания моделей представлений в вашем классе ViewModelLocator. Убедитесь, что все модели представлений, которые зависят от сообщения, созданы до модели представления, которая отправляет сообщение.
Например, в конструкторе вашего класса ViewModelLocator:
public ViewModelLocator()
{
if (s_messageReceiverVm == null)
{
s_messageReceiverVm = new MessageReceiverVM();
}
if (s_messageSenderVm == null)
{
s_messageSenderVm = new MessageSenderVM();
}
}
Хорошо, тогда. : -)
Вы можете привязать к методу в ViewModel, используя поведение.
Вот ссылка, которая поможет вам в этом. http://expressionblend.codeplex.com/