我正在学习使用Prism的DelgateCommand ....
在我的用户界面中,我有UserName文本框和PasswordBox:
<TextBox Name="_UserNameTextBox" Text="{Binding UserName, Mode=TwoWay}" />
<PasswordBox Name="_PasswordBox"></PasswordBox>
我的登录按钮:
<Button Name="button1" Command="{Binding LoginCommand, Mode=TwoWay}" CommandTarget="{Binding ElementName=_UserNameTextBox, Path=Text}">Login</Button>
然后我的ViewModel:
string _UserName = string.Empty;
public string UserName
{
get
{
return _UserName;
}
set
{
if (value != _UserName)
{
_UserName = value;
RaisePropertyChanged("UserName");
}
}
}
//For reference the password
PasswordBox _PasswordBox { get; set; }
public DelegateCommand<string> LoginCommand { get; set; }
public LoginViewModel(PasswordBox passwordBox)
{
_PasswordBox = passwordBox;
LoginCommand = new DelegateCommand<string>(
(
//Execute
(str) =>
{
Login(_PasswordBox.Password);
}
),
//CanExecute Delgate
(usr) =>
{
if (string.IsNullOrEmpty(usr) || string.IsNullOrEmpty(_PasswordBox.Password))
return false;
return true;
}
);
}
我可以看到我的UserName正确绑定,我确实将我的PasswordBox传递给ViewModel构造函数中的referece。当我执行应用程序时,Button被禁用,所以我知道绑定到命令。
但我从来没有看到我写的CanExecute delgate在我输入UserName和PasswordBox之后正在检查....并且从未启用...
那我做错了什么?
编辑:
=====
最终结果是......这个?
string _UserName = string.Empty;
public string UserName
{
get
{
return _UserName;
}
set
{
if (value != _UserName)
{
_UserName = value;
RaisePropertyChanged("UserName");
LoginCommand.RaiseCanExecuteChanged();
}
}
}
//For reference the password
PasswordBox _PasswordBox { get; set; }
public DelegateCommand<string> LoginCommand { get; set; }
public LoginViewModel(PasswordBox passwordBox)
{
_PasswordBox = passwordBox;
_PasswordBox.PasswordChanged += delegate(object sender, System.Windows.RoutedEventArgs e)
{
LoginCommand.RaiseCanExecuteChanged();
};
LoginCommand = new DelegateCommand<string>(
(
(str) =>
{
Login(_PasswordBox.Password);
}
),
(usr) =>
{
if (string.IsNullOrEmpty(usr) || string.IsNullOrEmpty(_PasswordBox.Password))
return false;
return true;
}
);
}
答案 0 :(得分:2)
一般来说,只要CanExecute
返回的效果值发生变化,就必须致电RaiseCanExecuteChanged
。在这种特定情况下,只要用户或密码字段的值发生更改,就需要调用它。但这非常困难,因为您的ViewModel实现完全错误。
这是你应该做的事情:
Username
和Password
属性。您需要明确地实现getter和setter(即它不能是自动属性)。LoginCommand.RaiseCanExecuteChanged
。以下是执行此操作时会发生的情况(让我们选择密码框作为示例):
LoginViewModel.Password
的值。RaiseCanExecuteChanged
,这会在您的命令中引发CanExecuteChanged
事件。CanExecute
以查看是否允许执行命令。true
,因此该按钮会自行激活。答案 1 :(得分:1)
您需要绑定Button.CommandParameter
(将传递给Execute
和CanExecute
),如果该绑定发生更改CanExecute
被重新评估,据我所知
(我认为您将CommandParameter
与CommandTarget
混淆,CommandTarget
未在命令中使用,它仅用于在某个元素上引发命令(可以与命令路由相关,例如