摘要:在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(this, new 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<string, string> _dataErrors = new Dictionary<string, string>();
        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(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion

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

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

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

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

)
                    _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");
                }
            }
        }

);
                        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>

  其最终运行结果如下:

  今天内容讲到这里了。

  源代码下载

Silverlight实例教程 - Validation客户端同步数据验证(转载)的更多相关文章

  1. Silverlight实例教程 - Validation用户提交数据验证捕获(转载)

    Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...

  2. Silverlight实例教程 - Validation服务器端异步数据验证(转载)

    摘要:本 篇实例,我们仍旧使用SilverlightValidationDemo项目,为了不和过去的验证方法冲突,这里我们创建一个新的数据成员类 Staff,该类实现INotifyDataErrorI ...

  3. Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧(转载)

    Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...

  4. Silverlight实例教程 - Validation数据验证基础属性和事件(转载)

    Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...

  5. Silverlight实例教程 - Validation数据验证开篇

    Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...

  6. Silverlight实例教程 - 自定义扩展Validation类,验证框架的总结和建议(转载)

    Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...

  7. Silverlight实例教程 – Datagrid,Dataform数据验证和ValidationSummary(转载)

    Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...

  8. Scrapy爬虫实例教程(二)---数据存入MySQL

    书接上回 实例教程(一) 本文将详细描述使用scrapy爬去左岸读书所有文章并存入本地MySql数据库中,文中所有操作都是建立在scrapy已经配置完毕,并且系统中已经安装了Mysql数据库(有权限操 ...

  9. Silverlight,Windows 8应用开发实例教程系列汇总

    Kevin Fan分享开发经验,记录开发点滴 Silverlight,Windows 8应用开发实例教程系列汇总 2012-06-18 01:05 by jv9, 2145 阅读, 3 评论, 收藏, ...

随机推荐

  1. 洛谷——P1152 欢乐的跳

    P1152 欢乐的跳 题目描述 一个n个元素的整数数组,如果数组两个连续元素之间差的绝对值包括了[1,n-1]之间的所有整数,则称之符合“欢乐的跳”,如数组1 4 2 3符合“欢乐的跳”,因为差的绝对 ...

  2. 11、Django实战第11天:templates模板继承

    Django模板的继承,它首先定义一个整体的框架(父类),然后动态的部分(子类)只需要重写自己本身的代码就可以了. 1.在templates目录下创建base.html 2.把org-list.htm ...

  3. 谜题27:变幻莫测的i值

    与谜题26中的程序一样,下面的程序也包含了一个记录在终止前有多少次迭代的循环.与那个程序不同的是,这个程序使用的是左移操作符(<<).你的任务照旧是要指出这个程序将打印什么.当你阅读这个程 ...

  4. python 统计发送请求到接收response的时间

    由于需要测试请求一个接口所耗用的时间,在网上查找资料也麻烦,所以自己总结一下 找到elapsed 函数 ,按照文档说的是获取请求发出的时间至响应到达经过的时间,,具体用法如下: 执行的结果是 微秒 单 ...

  5. 【贪心】【DFS】Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) C. Andryusha and Colored Balloons

    从任意点出发,贪心染色即可. #include<cstdio> #include<algorithm> using namespace std; int v[200010< ...

  6. 【暴力】UVALive - 4882 - Parenthesis

    就不断地扫整个序列,如果发现多余的括号就删除.大概复杂度还是O(n²)左右.如何判断不合法请详见代码. To a computer, there is no difference between th ...

  7. python操作mysql封装成类

    import pymysqlimport loggingimport sys # 加入日志#获取logger实例logger = logging.getLogger("baseSpider& ...

  8. Java高级架构师(一)第15节:带查询的分页、修改和删除页面

    @RequestMapping(value="toList",method=RequestMethod.GET) public String toList(@ModelAttrib ...

  9. Jackson使用ObjectManage#readValue传入泛型T的问题

    说明:没找到合适的方法,持续关注这个问题 参考: https://stackoverflow.com/questions/11664894/jackson-deserialize-using-gene ...

  10. winform treeview 绑定文件夹和文件

    转载:http://www.cnblogs.com/zhbsh/archive/2011/05/26/2057733.html #region treeview 绑定文件夹和文件 /// <su ...