为什么我的登录按钮总是被禁用?

Why is my Login button always disabled?

我有一个带有 x:Name=This 的弹出视图,上面有一个按钮,如下所示:

<Button Content="Log in" Command="{Binding Path=LoginCommand}" CommandParameter="{Binding ElementName=This}" />

这是为了获得对不可绑定 Password 属性 的访问权限,这是一种 SecureString 类型。

在我的 ctor 中,我像这样初始化命令:

public LoginPopupViewModel()
{
    LoginCommand = new DelegateCommand<IHavePassword>(
        LogUserIn,
        p => !string.IsNullOrWhiteSpace(Username));
}

我完全希望当我在 Username 中键入内容并更改焦点时,属性 更改通知将有助于启用“登录”按钮。它没有,所以我添加了额外的代码,但按钮仍然处于禁用状态。

public string Username
{
    get { return _username; }
    set
    {
        if (value == _username) return;
        _username = value;
        OnPropertyChanged();
        CommandManager.InvalidateRequerySuggested();
    }
}

如果我像下面这样更改 CanExecute 委托,只有这样按钮才会启用:

public LoginPopupViewModel()
{
    LoginCommand = new DelegateCommand<IHavePassword>(
        LogUserIn,
        p => true);
}

为什么这个按钮在其命令可以执行时仍保持禁用状态?

我试过示例程序,绑定似乎工作正常。我没有完整的源代码,但是当您希望命令检查它是否需要执行时,您需要在委托命令上使用 RaiseCanExecuteChanged。您是否检查过用户名的绑定是否正确? this.loginCommand.RaiseCanExecuteChanged();是答案的关键

    public LoginPopupViewModel()
        {
            this.loginCommand = new DelegateCommand(() =>
            {
                MessageBox.Show("Logged In Click");
            }, () =>
            {
                return !string.IsNullOrEmpty(UserName);
            });
        }

        private DelegateCommand loginCommand;
        private string userName;

        public ICommand LoginCommand
        {
            get { return loginCommand; }
        }

        public string UserName
        {
            get { return this.userName; }
            set
            {
                if (value == this.userName)
                {
                    return;
                }
                this.userName = value;
                OnPropertyChanged("UserName");
                this.loginCommand.RaiseCanExecuteChanged();
            }
        }

        public string Password { get; set; }