Подтвердить что ты не робот

Метод 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
}
4b9b3361

Ответ 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();
        }
    }