前文介绍过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命名空间。该接口主要被应用在需要对其进行验证的数据成员类。

代码

 1         #region IDataErrorInfo Members
 2 
 3         public string Error
 4         {
 5             get { throw new NotImplementedException(); }
 6         }
 7 
 8         public string this[string columnName]
 9         {
10             get { throw new NotImplementedException(); }
11         }
12 
13         #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中添加简单的逻辑代码,

        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>
复制代码

其最终运行结果如下:

今天内容讲到这里了。

源代码下载

转载于:https://www.cnblogs.com/kingdom_0/articles/2289983.html

Silverlight - Validation 客户端同步数据验证相关推荐

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

    在以往的Validation系列中,介绍了四种Silverlight验证机制: 基本异常验证机制: DataAnnotation验证机制: IDataErrorInfo客户端同步验证机制: INoti ...

  2. .NET客户端的数据验证实例

    Aapx代码块 <form id="form1" runat="server">     <asp:TextBox ID="Text ...

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

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

  4. AngularJS快速入门指南14:数据验证

    AngularJS表单和控件可以对用户输入的数据进行验证. 输入验证 在之前的章节中你已经了解了有关AngularJS表单和控件的相关内容. AngularJS表单和控件可以提供数据验证服务,并对不合 ...

  5. Silverlight实例教程 - Validation数据验证基础属性和事件

    上篇介绍了Silverlight的Validation数据验证的好处和概述,其中了解到Silverlight数据验证方法可以被抽象为语法验证和语义验证,其中前者是通过数据类型定义对比验证,而后者是通过 ...

  6. Silverlight – Datagrid,Dataform数据验证和ValidationSummary

    上一篇,我们讨论了,捕获用户提交数据验证.本篇将集中讨论Datagrid和Dataform两个数据控件的数据验证方法,其中,我们会附加介绍一个新的验证控件ValidationSummary. 概述 D ...

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

    上一篇,我们讨论了,捕获用户提交数据验证.本篇将集中讨论Datagrid和Dataform两个数据控件的数据验证方法,其中,我们会附加介绍一个新的验证控件ValidationSummary. 概述 D ...

  8. Silverlight Telerik控件学习:数据录入、数据验证

    相信很多人都听说过这句名言:garbage in ,garbage out ! 数据录入不规范(或错误)就象一颗定时炸弹,迟早会给系统带来麻烦,所以在数据录入时做好验证是很有必要的. 相对传统asp. ...

  9. SilverLight学习笔记--实际应用(一)(4):手把手建立一个Silverlight应用程序之同步数据校验1...

    现在我们的程序有了添加和删除以及修改功能,下面我们看一看如何让程序具备数据校验功能.我们将用两种方式实现数据的校验,一种是在客户端进行同步校验.另一种是在服务器端进行异步校验.   本篇我们先实现如何 ...

最新文章

  1. shell转换特殊的格式(%b)到时间戳  08/Dec/2016
  2. STM32 进阶教程 8 - 位带操作
  3. 全球及中国汽车涂料市场盈利预测与发展策略分析报告2022版
  4. 虚拟桌面启动后自动全屏
  5. Hologres揭秘:优化COPY,批量导入性能提升5倍+
  6. SAP CRM product hierarchy和category的三个问题问答
  7. C++学习——类的初始化
  8. SQL JOIN,你想知道的应该都有
  9. cookie——登录注册极简版
  10. Django-djangorestframework-异常模块-源码及自定义异常
  11. 概率论与数理统计(一)—— 联合概率、条件概率与边缘概率
  12. 绕过SQL注入限制的方法
  13. Inception介绍(MySQL自动化运维工具)
  14. python中卡方检验_python 使用卡方检验
  15. 特斯拉充电电流设置多大_特斯拉满电状态517公里,实际使用500公里。三种充电方式比较...
  16. X-Frame-Options响应头配置详解
  17. ios中达到Android中九妹图的效果
  18. 计算机专业哪些科目要好,2022考研:计算机专业需要准备哪些科目?
  19. PTA R7-5 Jack cheng的烦恼3
  20. 【sql+python】数据库与程序实践——某自来水公司收费系统

热门文章

  1. Gitlab自动触发Jenkins构建项目
  2. javascript举例介绍事件委托的典型使用场景
  3. 查找问题的利器 - Git Bisect
  4. leetcode 100.Same Tree
  5. Windows 11 高门槛吓退用户,Linux 成香饽饽?
  6. 致敬百年南开!南开大学作译者30本必读经典著作
  7. php mysql sqlite缓存_使用sqlite作为数据缓存
  8. 我最爱用的一款 Redis 可视化管理工具!好用到爆!!!
  9. Spring Boot官宣:正式弃用 Java 8
  10. Java 中的5个代码性能提升技巧,最高提升近10倍