此处下载源码
当form初始化显示,Register按钮应该启动和没有输入错误应该显示。如果用户点击注册按钮在特定的输入无效数据,form将显示输入错误和禁用的注册按钮。实现逻辑在标准的IDataErrorInfo接口。请查阅IDataErrorInfo接口(System.ComponentModel)MSDN文章
查阅IDataErrorInfo接口实现在RegistrationViewModel类
[POCOViewModel]
public class RegistrationViewModel : IDataErrorInfo {
...
string IDataErrorInfo.Error {
get {
IDataErrorInfo me = (IDataErrorInfo)this;
string error =
me[BindableBase.GetPropertyName(() => FirstName)] +
me[BindableBase.GetPropertyName(() => LastName)] +
me[BindableBase.GetPropertyName(() => Email)] +
me[BindableBase.GetPropertyName(() => Password)] +
me[BindableBase.GetPropertyName(() => ConfirmPassword)] +
me[BindableBase.GetPropertyName(() => Birthday)];
if (!string.IsNullOrEmpty(error))
return "Please check inputted data.";
return null;
}
}
string IDataErrorInfo.this[string columnName] {
get {
string firstNameProp = BindableBase.GetPropertyName(() => FirstName);
string lastNameProp = BindableBase.GetPropertyName(() => LastName);
string emailProp = BindableBase.GetPropertyName(() => Email);
string passwordProp = BindableBase.GetPropertyName(() => Password);
string confirmPasswordProp = BindableBase.GetPropertyName(() => ConfirmPassword);
string birthdayProp = BindableBase.GetPropertyName(() => Birthday);
string genderProp = BindableBase.GetPropertyName(() => Gender);
if (columnName == firstNameProp) {
if (FirstName == null || string.IsNullOrEmpty(FirstName))
return string.Format("You cannot leave the {0} field empty.", firstNameProp);
} else if (columnName == lastNameProp) {
if (LastName == null || string.IsNullOrEmpty(LastName))
return string.Format("You cannot leave the {0} field empty.", lastNameProp);
} else if (columnName == emailProp) {
if (Email == null || string.IsNullOrEmpty(Email))
return string.Format("You cannot leave the {0} field empty.", emailProp);
} else if (columnName == passwordProp) {
if (Password == null || string.IsNullOrEmpty(Password))
return string.Format("You cannot leave the {0} field empty.", passwordProp);
} else if (columnName == confirmPasswordProp) {
if (!string.IsNullOrEmpty(Password) && Password != ConfirmPassword)
return "These passwords do not match. Please try again.";
} else if (columnName == birthdayProp) {
if (Birthday == null || string.IsNullOrEmpty(Birthday.ToString()))
return string.Format("You cannot leave the {0} field empty.", birthdayProp);
} else if (columnName == genderProp) {
if (Gender == -1)
return string.Format("You cannot leave the {0} field empty.", genderProp);
}
return null;
}
}
}
启动IDataErrorInfo验证在XAML设置Binding.ValidatesOnDataErrors参数为true。设置绑定参数对于每一个form内的编辑器,包括ConfirmPassword编辑器
<dxlc:LayoutControl ... >
...
<dxe:TextEdit NullText="FIRST" ValidateOnEnterKeyPressed="True" ValidateOnTextInput="False">
<dxe:TextEdit.EditValue>
<Binding Path="FirstName" ValidatesOnDataErrors="True"
UpdateSourceTrigger="PropertyChanged" Mode="TwoWay"/>
</dxe:TextEdit.EditValue>
</dxe:TextEdit>
...
<dxe:PasswordBoxEdit EditValue="{Binding ConfirmPassword, ValidatesOnDataErrors=True}"
ValidateOnEnterKeyPressed="True" ValidateOnTextInput="True"/>
...
</dxlc:LayoutControl>
如果现在运行sample,将验证error当应用程序开始。
此问题是相关于输入验证IDataErrorInfo接口实现。修复此问题,重要验证错误没有返回在ViewModel如果一个用户没有点击注册按钮。
[POCOViewModel]
public class RegistrationViewModel : IDataErrorInfo {
...
public void AddEmployee() {
string error = EnableValidationAndGetError();
if(error != null) return;
EmployeesModelHelper.AddNewEmployee(FirstName, LastName, Email, Password, Birthday.Value);
}
bool allowValidation = false;
string EnableValidationAndGetError() {
allowValidation = true;
string error = ((IDataErrorInfo)this).Error;
if(!string.IsNullOrEmpty(error)) {
this.RaisePropertiesChanged();
return error;
}
return null;
}
string IDataErrorInfo.Error {
get {
if(!allowValidation) return null;
...
}
}
string IDataErrorInfo.this[string columnName] {
get {
if(!allowValidation) return null;
...
}
}
}
RegistrationViewModel没有返回一个错误直到用户点击注册按钮。输入数据有一个错误如果用户点击Register,不需要点击记录执行ViewModel验证逻辑在EnableValidationAndGetError方法。注意EnableValidationAndGetError调用RaisePropertiesChanged。此方法通常调用指南潜在数据更改;在这种情况,一个直线需要初始化验证进程。
验证几乎完成。剩余问题是Password字段。当用户修改Password字段,ConfirmPassword字段没有反应。你可以调用RaisePropertyChanged方法对于ConfirmPassword字段当Password字段更改。
[POCOViewModel]
public class RegistrationViewModel : IDataErrorInfo {
...
public virtual string Password { get; set; }
public virtual string ConfirmPassword { get; set; }
...
protected void OnPasswordChanged() {
this.RaisePropertyChanged(x => x.ConfirmPassword);
}
...
}
必须显示一个消息指示当注册成功和失败。DevExpress.Xpf.Mvvm库提供一个服务机制在Mvvm支持这些任务。
使用服务,首先需要定义一个服务显示消息框。DXMessageBoxService已经定义在MainView等级。取回服务从RegistrationViewModel,使用GetService<T>扩展方法。
[POCOViewModel]
public class RegistrationViewModel : IDataErrorInfo {
...
public void AddEmployee() {
string error = EnableValidationAndGetError();
if(error != null) {
OnValidationFailed(error);
return;
}
EmployeesModelHelper.AddNewEmployee(FirstName, LastName, Email, Password, Birthday.Value);
OnValidationSucceeded();
}
void OnValidationSucceeded() {
this.GetService<IMessageBoxService>().Show("Registration succeeded", "Registration Form", MessageBoxButton.OK);
}
void OnValidationFailed(string error) {
this.GetService<IMessageBoxService>().Show("Registration failed. " + error, "Registration Form", MessageBoxButton.OK);
}
...
}
代码之上声明两个方法-OnValidationSucceeded和OnValidationFailed-调用验证成功和失败,分别。这些方法获得IMessageBoxService服务定义在视图。服务接口提供Show方法显示方法框。
结果显示如下。
用户离开编辑框空白区域或者无效输入数据,这些相应消息将显示。
输入数据正确,用户通知注册成功完成。
此时,注册form是对于所有意图和目的,完成。