zoukankan      html  css  js  c++  java
  • (转)Silverlight数据校验之INotifyDataErrorInfo

    原文地址:http://www.cnblogs.com/PerfectSoft/archive/2012/03/01/2375007.html

       
    在Silverlight中,数据实体类的有效性校验有多种方法,比如说:运用TargetNullValue、FailBackValue、ValidatesOnExceptions.....,运用这些方法可以解决常见的问题,但是针对一些复杂性的数据校验,显然不是最有效的利器。比如说:在针对单个属性进行多重有效性验证的情况下,此时,可以灵活的运用INotifyDataErrorInfo接口。


        MSDN INotifyDataErrorInfor的定义如下:


        // Summary:
    // Defines members that data entity classes can implement to provide custom,
    // asynchronous validation support.
    public interface INotifyDataErrorInfo
    {
    // Summary:
    // Gets a value that indicates whether the object has validation errors.
    //
    // Returns:
    // true if the object currently has validation errors; otherwise, false.
    bool HasErrors { get; }

    // Summary:
    // Occurs when the validation errors have changed for a property or for the
    // entire object.
    event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

    // Summary:
    // Gets the validation errors for a specified property or for the entire object.
    //
    // Parameters:
    // propertyName:
    // The name of the property to retrieve validation errors for, or null or System.String.Empty
    // to retrieve errors for the entire object.
    //
    // Returns:
    // The validation errors for the property or object.
    IEnumerable GetErrors(string propertyName);
    }


       
    从INotifyDataErrorInfo的定义,就能够了解到它的作用。数据实体类可以继承INotifyDataErrorInfo,实现满足业务需求的有效性校验。下面以Student实体类实现INotifyDataErrorInfo接口为例。


        Student定义:


        public class Student : INotifyPropertyChanged,INotifyDataErrorInfo
    {
    //存放错误信息,一个Property可能对应多个错误信息
    private Dictionary<string, List<string>> errors = new Dictionary<string, List<string>>();

            //实现INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
    if (PropertyChanged != null)
    {
    PropertyChanged(this, e);
    }
    }

            //实现INotifyDataErrorInfo
    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

    public IEnumerable GetErrors(string propertyName)
    {
    if (string.IsNullOrEmpty(propertyName))
    {
    return null;
    }
    else
    {
    if (errors.ContainsKey(propertyName))
    {
    return errors[propertyName];
    }
    }
    return null;
    }

    public bool HasErrors
    {
    get
    {
    return (errors.Count > 0);
    }
    }


    private void SetErrors(string propertyName, List<string> propertyErrors)
    {
    errors.Remove(propertyName);
    errors.Add(propertyName, propertyErrors);
    if (ErrorsChanged != null)
    {
    ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
    }
    }

    private void ClearErrors(string propertyName)
    {
    errors.Remove(propertyName);
    if (ErrorsChanged != null)
    {
    ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
    }
    }


    private string name;
    private int age;

    public String Name
    {
    get
    {
    return name;
    }
    set
    {
    name = value;
    List<string> errors = new List<string>();
    bool valid = true;


    //数据校验
    if (name.Trim().Contains(" "))
    {
    errors.Add("姓名中不能包含空格");
    valid = false;
    }
    if (name.Length < 2 || name.Length > 4)
    {
    errors.Add("姓名的长度不能低于2高于4");
    valid = false;
    }

    if (!valid)
    {
    SetErrors("Name", errors);
    }
    else
    {
    ClearErrors("Name");
    }
    }
    }

    public int Age
    {
    get
    {
    return age;
    }
    set
    {
    age = value;
    if (age < 0 || age > 150)
    {
    List<string> errors = new List<string>();
    errors.Add("年龄不能小于0或大于150");
    SetErrors("Age", errors);
    }
    else
    {
    ClearErrors("Age");
    }
    }
    }
    }


        在MainPage XAML代码中,执行数据绑定时,必须设置ValidatesOnNotifyDataErrors = True。


    <Grid x:Name="LayoutRoot" Background="White" BindingValidationError="LayoutRoot_BindingValidationError">
    <Grid.RowDefinitions>
    <RowDefinition Height="40"></RowDefinition>
    <RowDefinition Height="40"></RowDefinition>
    <RowDefinition Height="40"></RowDefinition>
    <RowDefinition Height="Auto"></RowDefinition>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
    <ColumnDefinition></ColumnDefinition>
    <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <TextBlock Text="姓名:" HorizontalAlignment="Right" VerticalAlignment="Center"></TextBlock>
    <TextBox x:Name="txtName" Text="{Binding Name, Mode=TwoWay, ValidatesOnExceptions=True,
    ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}" Width="150" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Center">
    </TextBox>
    <TextBlock Text="年龄:" HorizontalAlignment="Right" Grid.Row="1" VerticalAlignment="Center"></TextBlock>
    <TextBox x:Name="txtAge" Text="{Binding Age, Mode=TwoWay, ValidatesOnExceptions=True,
    ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}" Width="150" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center">
    </TextBox>
    <Button x:Name="Submit" Content="Submit The Data" HorizontalAlignment="Left" Grid.Row="2" Grid.Column="1" Click="Submit_Click" VerticalAlignment="Center"></Button>
    <TextBlock x:Name="Summary" Text="无任何错误信息" VerticalAlignment="Center" Grid.Column="1" Grid.Row="3"></TextBlock>
    </Grid>


        MainPage 后台代码:


            public MainPage()
    {
    InitializeComponent();

    Student product = new Student();
    LayoutRoot.DataContext = product;
    }

    private void LayoutRoot_BindingValidationError(object sender, ValidationErrorEventArgs e)
    {
    //可能没有Exception,但是存在错误信息
    if (e.Error.Exception != null)
    {
    //异常处理代码
    }
    else
    {
    Summary.Text = e.Error.ErrorContent.ToString();
    txtName.Focus();
    }
    }


        运行结果:



        如果要实现复杂的数据验证,INotifyDataErrorInfo也是一个不错的选择,有不足之处,请大家指出。

  • 相关阅读:
    LintCode Python 简单级题目 488.快乐数
    LintCode Python 简单级题目 100.删除排序数组中的重复数字 101.删除排序数组中的重复数字II
    LintCode Python 简单级题目 373.奇偶分割数组
    LintCode Python 简单级题目 39.恢复旋转排序数组
    LintCode Python 简单级题目 35.翻转链表
    LintCode Python 简单级题目 451.两两交换链表中的节点
    LintCode Python 简单级题目 174.删除链表中倒数第n个节点
    aws查看官方centos镜像imageid
    linux shell脚本查找重复行/查找非重复行/去除重复行/重复行统计
    php配置优化-生产环境应用版
  • 原文地址:https://www.cnblogs.com/fcsh820/p/2377568.html
Copyright © 2011-2022 走看看