Nar*_*esh 20 wpf command prism
我正在使用两个TextBox(用户名和密码)和一个Login按钮编写一个简单的登录UserControl.我希望只有在填写用户名和密码字段时才启用"登录"按钮.我使用的是Prism和MVVM.LoginViewModel包含一个名为LoginCommand的属性,该属性绑定到Login按钮.我的ViewModel中有一个CanLoginExecute()方法,但只有在应用程序启动时才会触发,然后再也不会触发.因此,从不启用"登录"按钮.我错过了什么?
这是我的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}" />
Run Code Online (Sandbox Code Playgroud)
这是我的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
}
Run Code Online (Sandbox Code Playgroud)
oll*_*SFT 42
绑定控件很可能永远不再要求CanExecute状态.每当检测到更改命令的CanExecute状态的条件时,您需要在DelegateCommand上调用RaiseCanExecuteChanged方法.这表示绑定控件更新CanExecute状态.
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();
}
}
Run Code Online (Sandbox Code Playgroud)
从Prism6开始,DelegateCommand
可以“观察”您的财产。意味着每次您的属性更改时,都会调用CanExecute-Method。好消息是您摆脱RaiseCanExecuteChanged
了Propertysetter。如果要观察更多属性,也可以链式调用该方法:
public LoginViewModel()
{
this.LoginCommand =
new DelegateCommand<object>(
this.LoginExecute, this.CanLoginExecute).ObservesProperty(() => Username).ObservesProperty(() => Password);
}
Run Code Online (Sandbox Code Playgroud)
此外,如果只希望根据布尔属性的状态调用DelegateCommand,则可以使用 .ObservesCanExecute(()=> BoolProp)
public LoginViewModel()
{
this.LoginCommand =
new DelegateCommand<object>(
this.LoginExecute).ObservesCanExecute(()=> IsServerOnline).ObservesProperty(() => Username).ObservesProperty(() => Password);
}
Run Code Online (Sandbox Code Playgroud)
您this.CanLoginExecute
不再需要。
归档时间: |
|
查看次数: |
23805 次 |
最近记录: |