wpf devexpress 使用IDataErrorInfo实现input验证

此处下载源码

当form初始化显示,Register按钮应该启动和没有输入错误应该显示。如果用户点击注册按钮在特定的输入无效数据,form将显示输入错误和禁用的注册按钮。实现逻辑在标准的IDataErrorInfo接口。请查阅IDataErrorInfo接口(System.ComponentModel)MSDN文章

查阅IDataErrorInfo接口实现在RegistrationViewModel类

cs 复制代码
[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编辑器

XML 复制代码
<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如果一个用户没有点击注册按钮。

cs 复制代码
[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字段更改。

cs 复制代码
[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>扩展方法。

cs 复制代码
[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是对于所有意图和目的,完成。

相关推荐
月落.4 小时前
WPF的<ContentControl>控件
wpf
就是有点傻4 小时前
WPF中的依赖属性
开发语言·wpf
wangnaisheng4 小时前
【WPF】把一个Window放在左上角/右上角顶格显示
wpf
WineMonk4 小时前
.NET WPF CommunityToolkit.Mvvm框架
.net·wpf·mvvm
月落.4 小时前
WPF中的INotifyPropertyChanged接口
wpf
界面开发小八哥4 小时前
界面控件DevExpress WPF中文教程:Data Grid——卡片视图设置
.net·wpf·界面控件·devexpress·ui开发
平凡シンプル4 小时前
WPF 打包
wpf
VickyJames4 小时前
基于XAML框架和跨平台项目架构设计的深入技术分析
wpf·开源分享·unoplatform·winui3·项目架构
冷眼Σ(-᷅_-᷄๑)8 小时前
WPF缩放动画和平移动画叠加后会发生什么?
wpf·动画
△曉風殘月〆10 小时前
WPF MVVM入门系列教程(二、依赖属性)
c#·wpf·mvvm