zoukankan      html  css  js  c++  java
  • 在 WPF 中进行表单验证

    WPF的表单验证,自然比不上WEB多姿多彩。一般有三种方式进行表单验证:

    1. 代码直接验证(不少人直接用 MessageBox  弹出消息,Windows 的老传统),虽然够醒目,却太过打扰用户,不好。

    2. 通过异常验证(数据绑定,并设置 ValidatesOnExceptions=True ),调试时烦死人,不好。

    3. 通过内置接口 IDataErrorInfo 、INotifyDataErrorInfo 进行验证(数据绑定),这应该是目前较为理想的验证方式。这两个接口都位于 System.ComponentModel 空间,与 INotifyPropertyChanged 在一起。

     

    只说第三种验证方式。

    这两个接口,个人较喜欢第二个,原因是第一个接口不太灵活,而且是为了兼容而存在的,不推荐使用。第二要灵活得多。

     

    为了突出验证消息的提示效果,可添加这样一个样式(定义为字典资源,用起来更方便):

    <Style TargetType="TextBox">
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <DockPanel>
                        <TextBlock DockPanel.Dock="Bottom" Foreground="Red"
                                    Text="{Binding ElementName=adornedElement, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"></TextBlock>
                        <Border BorderBrush="Red" BorderThickness="1">
                            <AdornedElementPlaceholder Name="adornedElement"></AdornedElementPlaceholder>
                        </Border>
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    一、首先定义一个集合,用于保存验证消息:

    private readonly IDictionary<string, IList<string>> m_errors = new Dictionary<string, IList<string>>();

     

    二、下面是实现接口,具体用法见注释:

    // 该方法仅为简化属性调用。CallerMemberName 特性是 .net 4.5 才加入的,位于 System.Runtime.CompilerServices 空间。
    public
    void Validate(Func<bool> valid, string error, [CallerMemberName]string prop = null) { if (valid()) ClearError(prop); else SetError(new[] { error }, prop); OnChanged(prop); }
    // 验证属性事件。
    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; // 属性更改事件。
    public event PropertyChangedEventHandler PropertyChanged; // 该方法由 wpf 调用。 public IEnumerable GetErrors(string propertyName) { if (string.IsNullOrEmpty(propertyName)) return null;    // SelectMany 方法很有用,若没有它,错误消息不能正确显示,除非你重写集合,并重写其 ToString 方法。它帮你省了很多麻烦。 var errors = m_errors.SelectMany(e => e.Value); return errors; } // 添加错误消息。 public void SetError(IList<string> errors, string prop) { m_errors.Remove(prop); m_errors.Add(prop, errors); OnError(prop); } // 清除错误消息。 public void ClearError(string prop) { m_errors.Remove(prop); OnError(prop); } // 验证属性时调用。 private void OnError(string prop) { ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(prop)); }

    三、属性这样调用验证代码(以及更新事件):

    public string Password
    {
        get { return m_password; }
        set
        {
            m_password = value;
         // 由于第三种验证方式比较温和,不能像异常那样阻止属性值更新,因此该方法放在下面没有问题。 Validate(() => !Regex.IsMatch(value, "4"), "数字 4 不祥"); } }

     

    四、前台代码并没有什么特殊的,只要你别忘了应用上面的样式。 ValidatesOnNotifyDataErrors=True 可不写,但建议写上,有提示作用:

    <TextBox Text="{Binding Path=Password, ValidatesOnNotifyDataErrors=True}"></TextBox>

     

    完。

  • 相关阅读:
    存储函数
    Laravel的请求声明周期
    哪只猴子可以当大王
    有多少苹果用来分赃
    SqlDataAdapter使用小结
    主键与外键
    SQL server 操作相关
    C# 窗体相关知识
    C#中winform DataGridView常用修改点
    maven 坐标获取方式
  • 原文地址:https://www.cnblogs.com/yyzj/p/7067431.html
Copyright © 2011-2022 走看看