Метод WPF-Prism CanExecute не называется
Я кодирую простой логин UserControl с двумя текстовыми полями (имя пользователя и пароль) и кнопкой входа. Я хочу, чтобы кнопка "Войти" включалась только при заполнении полей имени пользователя и пароля. Я использую Prism и MVVM. LoginViewModel содержит свойство LoginCommand, которое связано с кнопкой Login. У меня есть метод CanLoginExecute() в моей модели ViewModel, но он срабатывает только тогда, когда приложение появляется, а затем никогда больше. Таким образом, кнопка "Логин" никогда не включена. Что мне не хватает?
Здесь мой xaml:
<TextBox x:Name="username"
Text="{Binding Path=Username, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
<TextBox x:Name="password"
Text="{Binding Path=Password, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
<Button Content="Login"
cmnd:Click.Command="{Binding LoginCommand}" />
Здесь моя ViewModel
class LoginViewModel : IDataErrorInfo, INotifyPropertyChanged
{
public LoginViewModel()
{
this.LoginCommand =
new DelegateCommand<object>(
this.LoginExecute, this.CanLoginExecute);
}
private Boolean CanLoginExecute(object dummyObject)
{
return (string.IsNullOrEmpty(Username) ||
string.IsNullOrEmpty(Password)) ? false : true;
}
private void LoginExecute(object dummyObject)
{
if (CheckCredentials(Username, Password))
{
....
}
}
#region IDataErrorInfo Members
public string Error
{
get { throw new NotImplementedException(); }
}
public string this[string columnName]
{
get
{
string result = null;
if (columnName == "Username")
{
if (string.IsNullOrEmpty(Username))
result = "Please enter a username";
}
else if (columnName == "Password")
{
if (string.IsNullOrEmpty(Password))
result = "Please enter a password";
}
return result;
}
}
#endregion // IDataErrorInfo Members
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion // INotifyPropertyChanged Members
#region Properties
private String _username;
public String Username
{
get { return _username; }
set
{
if (value == _username)
return;
_username = value;
this.OnPropertyChanged("Username");
}
}
private String _password;
public String Password
{
get { return _password; }
set
{
if (value == _password)
return;
_password = value;
this.OnPropertyChanged("Password");
}
}
public ICommand LoginCommand { get; private set; }
#endregion // Properties
}
Ответы
Ответ 1
Скорее всего, связанный элемент управления никогда не запрашивает состояние CanExecute. Вы должны вызвать метод RaiseCanExecuteChanged на делететом Commommand всякий раз, когда вы обнаруживаете условие, которое изменяет состояние команды CanExecute. Это сигнализирует связанному управлению, чтобы обновить состояние CanExecute.
Ответ 2
Код для RaiseCanExecuteChanged:
private void RaiseCanExecuteChanged()
{
DelegateCommand<object> command = LoginCommand as DelegateCommand<object>;
command.RaiseCanExecuteChanged();
}
public const string UsernameProperty = "Username";
private String _username;
public String Username
{
get { return _username; }
set
{
_username = value;
this.NotifyPropertyChanged(UsernameProperty);
RaiseCanExecuteChanged();
}
}