使用IDataErrorInfo的WPF MVVM验证
本文关键字:MVVM 验证 WPF IDataErrorInfo 使用 | 更新日期: 2023-09-27 18:12:05
我已经创建了一个Person MVVM模型,需要进行验证。我正在使用IDataErrorInfo类并验证用户。但是,当屏幕加载时,文本框已经是红色/验证,表明该字段需要填写。我相信这是因为我在InitializeComponent中绑定了PersonViewModel。我试图使用LostFocus更新触发器,但没有做任何事情。
这是我的PersonViewModel: public class PersonViewModel : IDataErrorInfo
{
private string _firstName;
private string _lastName;
public string LastName { get; set; }
public string Error
{
get { throw new NotImplementedException(); }
}
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
public string this[string columnName]
{
get
{
string validationResult = String.Empty;
switch(columnName)
{
case "FirstName":
validationResult = ValidateFirstName();
break;
case "LastName":
validationResult = ValidateLastName();
break;
default:
throw new ApplicationException("Unknown property being validated on the Product");
}
return validationResult;
}
}
private string ValidateLastName()
{
return String.IsNullOrEmpty(LastName) ? "Last Name cannot be empty" : String.Empty;
}
private string ValidateFirstName()
{
return String.IsNullOrEmpty(FirstName) ? "First Name cannot be empty" : String.Empty;
}
}
这里是XAML:
<StackPanel>
<TextBlock>First Name</TextBlock>
<TextBox Text="{Binding FirstName, ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}" Background="Gray"></TextBox>
<TextBlock>Last Name</TextBlock>
<TextBox Text="{Binding LastName, ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}" Background="Gray"></TextBox>
</StackPanel>
MainWindow.cs:
public MainWindow()
{
InitializeComponent();
_personViewModel = new PersonViewModel();
this.DataContext = _personViewModel;
}
我错过了什么吗?我不希望在屏幕加载时触发验证。我只希望它在用户失去文本框焦点时被触发。
与其与默认情况下WPF的工作方式抗争,不如考虑重新定义UI,以便错误显示"适合"屏幕加载和数据输入错误的场景。此外,用户应该在空白表单上提供一些所需内容的提示。
创建一个方法来进行验证,并将验证结果存储在字典中:
private Dictionary<string, string> _validationErrors = new Dictionary<string, string>();
public void Validate(string propertyName)
{
string validationResult = null;
switch(propertyName)
{
case "FirstName":
validationResult = ValidateFirstName();
break;
}
//etc.
}
//Clear dictionary properly here instead (You must also handle when a value becomes valid again)
_validationResults[propertyName] = validationResult;
//Note that in order for WPF to catch this update, you may need to raise the PropertyChanged event if you aren't doing so in the constructor (AFTER validating)
}
然后将ViewModel更新为:
- 如果存在,让索引器返回_validationErrors的结果。
- 在你的设置中调用Validate()。
- 可选,在Validate()中,如果propertyName为null,验证所有属性。
WPF将调用索引器来显示错误,并且由于您正在返回某些内容,它将认为存在错误。除非您使用此解决方案显式调用Validate(),否则不会。
编辑:还请注意,现在有一个更有效的方法来实现验证在。net 4.5称为INotifyDataErrorInfo.