使用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; 

        }

我错过了什么吗?我不希望在屏幕加载时触发验证。我只希望它在用户失去文本框焦点时被触发。

使用IDataErrorInfo的WPF MVVM验证

与其与默认情况下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更新为:

  1. 如果存在,让索引器返回_validationErrors的结果。
  2. 在你的设置中调用Validate()。
  3. 可选,在Validate()中,如果propertyName为null,验证所有属性。

WPF将调用索引器来显示错误,并且由于您正在返回某些内容,它将认为存在错误。除非您使用此解决方案显式调用Validate(),否则不会。

编辑:还请注意,现在有一个更有效的方法来实现验证在。net 4.5称为INotifyDataErrorInfo.