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也是一个不错的选择,有不足之处,请大家指出。

  • 相关阅读:
    卡特兰数,高精度卡特兰数
    SqlServer表中两条全然同样的记录,怎样删除当中1条
    微信.NET 微信开发 自己主动内容回复 ASP.NET C#代码
    RadHat搭建内网YUM源server
    2014上海全国邀请赛题解 HDOJ 5090-5099
    Enum枚举类|注解Annotation
    Galera 10.0.20 on CentOS 6.6
    CSS布局那点事儿
    利用CSS制作脸书
    《民国枭雄杜月笙》—— 听后总结
  • 原文地址:https://www.cnblogs.com/fcsh820/p/2377568.html
Copyright © 2011-2022 走看看