未调用 WPF-Prism CanExecute 方法

标签 wpf prism command

我正在编写一个带有两个文本框(用户名和密码)和一个登录按钮的简单登录用户控件。我希望仅在填写用户名和密码字段时才启用登录按钮。我使用的是 Prism 和 MVVM。 LoginViewModel 包含一个名为 LoginCommand 的属性,该属性绑定(bind)到 Login 按钮。我的 ViewModel 中有一个 CanLoginExecute() 方法,但它仅在应用程序启动时触发,然后再也不会触发。所以登录按钮永远不会启用。我错过了什么?

这是我的xml:

<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}" />

这是我的 View 模型
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
}

最佳答案

从 Prism6 开始 DelegateCommand可以“观察”你的属性(property)。意味着每次您的属性发生变化时都会调用 CanExecute-Method。好在你摆脱了RaiseCanExecuteChanged在属性 setter 中。如果您想观察更多属性,也可以链式调用该方法:

public LoginViewModel()
{
    this.LoginCommand =
        new DelegateCommand<object>(
            this.LoginExecute, this.CanLoginExecute).ObservesProperty(() => Username).ObservesProperty(() => Password);
}

此外,如果您只想根据 bool 属性的状态调用您的 DelegateCommand,您可以使用 .ObservesCanExecute(()=> BoolProp)
public LoginViewModel()
{
    this.LoginCommand =
        new DelegateCommand<object>(
            this.LoginExecute).ObservesCanExecute(()=> IsServerOnline).ObservesProperty(() => Username).ObservesProperty(() => Password);
}

你不需要this.CanLoginExecute了。

关于未调用 WPF-Prism CanExecute 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2444927/

相关文章:

c# - 如何在 wpf 中使用 Prism 打开新的模态对话框

c# - 如何通过按按钮启动新的 WPF 页面

c# - 将参数传递给自定义模板

c# - 在 C#/XAML 中旋转位图图像

c# - 为 System.Windows.Shapes.Path 动态设置 Path.Data

c# - 汉堡菜单 Prism xamarin形式?

c# - app.xaml.cs 与 MainViewmodel 通信的问题

c# - 检测是否在 NavigationContext 中调用了 GoBack()

.net - ICommand 如何以及在何处融入整个 WPF MVVM 模式?

delphi - 如何从 delphi 7 应用程序运行 mklink 系统命令 (cmd.exe)