zoukankan      html  css  js  c++  java
  • Silverlight实例教程

    摘要:在Silverlight 4中,Silverlight Validation有相对的改进,本篇将介绍Silverlight 4中新加入的验证机制功能,IDataErrorInfo客户端同步验证机制

      Silverlight 4 Validation验证实例系列

      前文介绍过Silverlight Validation中两个数据验证机制,ValidatesOnExceptions异常捕获验证机制和DataAnnotation验证机制,这两种 验证机制,是在Silverlight 3 Validation Framework推出的,其运行方式类似,都是当异常抛出后,应用对异常信息进行捕获,并显示在客户端。在Silverlight 4中,Silverlight Validation有相对的改进,本篇将介绍Silverlight 4中新加入的验证机制功能,IDataErrorInfo客户端同步验证机制。

      Silverlight 4 IDataErrorInfo接口概述

      相信熟悉WPF的开发人员都知道,WPF也具有IdataErrorInfo接口,其接口可以无需抛出任何异常,即可对数据进行验证。而 Silverlight的IDataErrorInfo接口就是从WPF中转化来的。与前面两种验证机制相比,Silverlight 4 IDataErrorInfo提供的同步验证方式,不再需要基于异常抛出的基础上来激活验证,简单的理解,就是当值验证失败的时候,不会抛出任何异常信 息。这种验证机制,相对前两种验证机制来说更加灵活。

      Silverlight 4 IDataErrorInfo接口类成员

      IDataErrorInfo接口,位于System.ComponentModel命名空间。该接口主要被应用在需要对其进行验证的数据成员类。

             #region IDataErrorInfo Members
             public string Error
             {
                 get { throw new NotImplementedException(); }
             }
     
             public string this[string columnName]
             {
                 get { throw new NotImplementedException(); }
             }
            #endregion

      IDataErrorInfo接口具有两个属性:

      1. Error: 该属性为验证设置属性错误提示信息;

      2. Item: 该属性为错误信息集合,其中索引值为属性名,将其对应的错误信息,设置到指定的被验证控件中;

      从MSDN对IdataErrorInfo接口的解释中可以看到,IDataErrorInfo接口,没有任何事件方法被预先定义。也就是 说,IDataErrorInfo接口本身不具备自动激活验证功能。简单的可以理解成为,当验证错误产生时,该错误信息不会自动捕获,然后显示到用户客户 端上。解决该问题,需要引入另外一个接口INotifyPropertyChanged。对Silverlight早期版本熟悉的开发人员,应该对INotifyPropertyChanged接口并不陌生,该接口主要功能是当数据成员改变时发出通知到客户端,是Silverlight中最常用的一个接口,这里对该接口不再赘述。

    public class Customer  : INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
       
    private void NotifyPropertyChanged(String info)
        {
            
    if (PropertyChanged != null)
            {
                PropertyChanged(
    thisnew PropertyChangedEventArgs(info));
            }
        }
        public string CustomerName
        {
            
    get
            {
                
    return this.customerNameValue;
            }
            
    set
            {
                
    if (value != this.customerNameValue)
                {
                    
    this.customerNameValue = value;
                    NotifyPropertyChanged(
    "CustomerName");
                }
            }
        }

      在使用了INotifyPropertyChanged接口后,每当数据成员验证错误产生时,都会执行IDataErrorInfo接口,检测Error和Item属性。但是仅仅使用INotifyPropertyChanged接口,还无法正常将错误信息显示在客户端,同时也需要在客户端添加新的绑定验证属性ValidatesOnDataErrors, 该属性在默认绑定情况下是False,如果使用IDataErrorInfo接口,则需要使用True,这时,客户端才会显示IDataErrorInfo接口被执行后产生的验证错误信息。

    <TextBox Text="{Binding CustomerName,Mode=TwoWay,ValidatesOnDataErrors=true}" />

      讲到这里,我们可以结合前两篇讲解的绑定验证属性,来理解IDataErrorInfo接口。使用IDataErrorInfo接口,必须结合 INotifyPropertyChanged接口使用,否则UI无法获取到相对应属性的错误关联信息。而使用IDataErrorInfo接口绑定验证 属性时,在客户端控件内容绑定中使用ValidatesOnDataErrors = True,另外,如果需要使用BindingValidationError事件,在客户端控件内容中,需要再绑定 NotifyOnValidationError = True,如果需要对异常进行捕获相应,同时,也需要绑定ValidatesOnExceptions = True。

      IDataErrorInfo接口使用实例演示

      本实例仍旧使用上一篇的实例代码,在其基础上添加对IDataErrorInfo接口的调用,首先在User数据成员类中,执行IDataErrorInfo和INotifyPropertyChanged接口。

           #region IDataErrorInfo Members
           
    private string _dataError = string.Empty;
            
    public string Error
            {
                
    get { return _dataError; }
            }

            
    private Dictionary<stringstring> _dataErrors = new Dictionary<stringstring>();
            
    public string this[string columnName]
            {
                
    get 
                {
                    
    if (_dataErrors.ContainsKey(columnName))
                        
    return _dataErrors[columnName];
                    
    else
                        
    return null;
                }
            }

            
    #endregion

            
    #region INotifyPropertyChanged Members

            
    public event PropertyChangedEventHandler PropertyChanged;
            
    protected void NotifyPropertyChanged(string propertyName)
            {
                
    if (PropertyChanged != null)
                    PropertyChanged(
    thisnew PropertyChangedEventArgs(propertyName));
            }
           
    #endregion

      其中IDataErrorInfo中定义的Dictionary是验证错误集合。而INotifyPropertyChanged是最简单的当数据成员改变时返回通知到客户端,其中没有过多的逻辑代码。

      我们使用最简单的数据成员生成一个验证错误,IDataErrorInfo捕获显示作为演示, 在User类中,添加一个Address地址数据成员。

            private string _address;
            
    public string address
            {
                
    get
                {
                    
    return _address;
                }
                
    set
                {
                    _address 
    = value;
                }
            }

      然后在set中添加简单的逻辑代码。

            private string _address;
            
    public string address
            {
                
    get
                {
                    
    return _address;
                }
                
    set
                {
                    
    if (string.IsNullOrEmpty(value))
                        _dataErrors[
    "address"= "地址必须填写";
                    
    else if (value.Trim().Length < 6)
                        _dataErrors[
    "address"= "地址至少6个字";
                    
    else
                        
    if (_dataErrors.ContainsKey("address"))
                            _dataErrors.Remove(
    "address");

                    _address 
    = value;
                    NotifyPropertyChanged(
    "address");
                }
            }

      修改前台,添加新的输入框,另外绑定输入框内容到address。

    <StackPanel Orientation="Horizontal" Margin="5">
                    
    <TextBlock Text="地   址: " VerticalAlignment="Center"/>
                    
    <TextBox x:Name="txtAddress" Width="200" DataContext="{Binding Source={StaticResource UserDataContext}}" Text="{Binding Path=address, Mode=TwoWay, ValidatesOnDataErrors=True}" />
    </StackPanel>

      其运行结果为:

      下面,我们做一个较为复杂一些的数据验证,学生成绩对应表:

      A   -  90-100分

      B   -  80-89分

      C   -  70-79分

      D   -  60-69分

      F   -  0-59分

      在这个实例中,我们对多个数据成员进行客户端数据验证。添加两个新数据成员,gradelevel和graderange,其中使用独立的验证函数ValidateGradeLevelandRange进行数据验证。

            private string _gradelevel;
            
    public string gradelevel
            {
                
    get { return _gradelevel; }
                
    set
                {
                    
    if (ValidateGradeLevelandRange(value,graderange))
                    {
                        _gradelevel 
    = value;
                        NotifyPropertyChanged(
    "gradelevel");
                    }
                }
            }

            
    private decimal _graderange;
            
    public decimal graderange
            {
                
    get { return _graderange; }
                
    set
                {
                    
    if (ValidateGradeLevelandRange(gradelevel, value))
                    {
                        _graderange 
    = value;
                        NotifyPropertyChanged(
    "graderange");
                    }
                }
            }
            #region Customize Validation
            
    private bool ValidateGradeLevelandRange(string level, decimal range)
            {
                
    bool isValid = false;

                
    if (level == null)
                {
                    _dataErrors[
    "gradelevel"= "成绩等级必须是A,B,C,D,F";
                    
    return false;
                }
                
    else
                {
                    
    switch (level.ToUpper())
                    {
                        
    case "A":
                            isValid 
    = (range >= 90 && range <= 100);
                            
    break;
                        
    case "B":
                            isValid 
    = (range >= 80 && range <= 89);
                            
    break;
                        
    case "C":
                            isValid 
    = (range >= 70 && range <= 79);
                            
    break;
                        
    case "D":
                            isValid 
    = (range >= 60 && range <= 69);
                            
    break;
                        
    case "F":
                            isValid 
    = (range >= 0 && range <= 59);
                            
    break;
                        
    default:
                            _dataErrors[
    "gradelevel"= "成绩等级必须是A,B,C,D,F";
                            
    return false;
                    }
                }

                
    if (isValid)
                {
                    
    if (_dataErrors.ContainsKey("gradelevel"))
                        _dataErrors.Remove(
    "gradelevel");
                    
    if (_dataErrors.ContainsKey("graderange"))
                        _dataErrors.Remove(
    "graderange");
                }
                
    else
                {
                    _dataErrors[
    "gradelevel"= "成绩等级和成绩范围不符合";
                    _dataErrors[
    "graderange"= "成绩范围和成绩等级不符合";
                }

                
    return isValid;
            }
            
    #endregion

      在前台添加两个成绩输入框。

                <StackPanel Orientation="Horizontal" Margin="5">
                    
    <TextBlock Text="成绩等级: " VerticalAlignment="Center"/>
                    
    <TextBox x:Name="txtGradeLevel" Width="200" DataContext="{Binding Source={StaticResource UserDataContext}}" Text="{Binding Path=gradelevel, Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=False, ValidatesOnExceptions=True}" />
                
    </StackPanel>
                
    <StackPanel Orientation="Horizontal" Margin="5">
                    
    <TextBlock Text="成绩范围: " VerticalAlignment="Center"/>
                    
    <TextBox x:Name="txtGradeRange" Width="200" DataContext="{Binding Source={StaticResource UserDataContext}}" Text="{Binding Path=graderange, Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=False, ValidatesOnExceptions=True}" />
                
    </StackPanel>

      其最终运行结果如下:

      今天内容讲到这里了。

      源代码下载

  • 相关阅读:
    保障系统的稳定性
    Ubuntu 16.04开启SSH服务
    Linux中tty是什么(tty1~7)
    Linux显示使用命令who(转)
    Linux去重命令uniq(转)
    Linux文字分段裁剪命令cut(转)
    Linux排序命令sort(转)
    Linux查找字符串命令grep(转)
    Linux文件查找命令find(转)
    Ubuntu查看和写入系统日志
  • 原文地址:https://www.cnblogs.com/sandea/p/3289869.html
Copyright © 2011-2022 走看看