CSLA.Net学习(3)INotifyPropertyChanged和IDataErrorInfo

时间:2023-01-24 15:10:45

今天晕晕糊糊的看CSLA.net,希望能找到验证数据正确性的方法,还是摸索出了INotifyPropertyChanged, IDataErrorInfo接口的使用方法,通过INotifyPropertyChanged实现了响应属性改变的事件,通过 IDataErrorInfo接口实现了在DataGridView或者GridControl中显示验证信息。

先看一个数据实体的抽象类:

  public abstract class BaseModel : INotifyPropertyChanged, INotifyPropertyChanging, IDataErrorInfo
{
protected BusinessRules mBusinessRules = new BusinessRules(); public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangingEventHandler PropertyChanging; public BaseModel()
{
mBusinessRules.info = this;
AddRule();
} public virtual void AddRule()
{ } protected virtual void PropertyHasChanged(string name)
{
var propertyNames = mBusinessRules.CheckRules(name); foreach (var item in propertyNames)
OnPropertyChanged(item);
} protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } protected virtual void OnPropertyChanging(string propertyName)
{
if (PropertyChanging != null)
PropertyChanging.Invoke(this, new PropertyChangingEventArgs(propertyName)); } #region IDataErrorInfo string IDataErrorInfo.Error
{
get
{
return "Hello";
}
} string IDataErrorInfo.this[string columnName]
{
get { return mBusinessRules.GetBrokenRules(columnName); }
} #endregion }

其中的BusinessRules对象mBusinessRules主要负责验证属性的正确性,这里只实现了一个粗糙版本的,没有抽象出验证规则Rule类。

将属性名和验证规则增加到mBusinessRules对象中,通过IDataErrorInfo的IDataErrorInfo.Error属性和IDataErrorInfo.this[string columnName]索引器验证每一列的正确性。Error是行头显示的提示信息。这里用到了lamda表达式和属性的遍历。

  public class BusinessRules
{
List<string> names = new List<string>();
List<string> exp = new List<string>();
public object info;//指向对象本身 public List<string> CheckRules(string name)
{
return names;
} public string GetBrokenRules(string columnName)
{
for (int i = ; i < names.Count; i++)
{
List<object> list = new List<object>();
if (info == null) return null;
Type t = info.GetType();
IEnumerable<System.Reflection.PropertyInfo> property = from pi in t.GetProperties() where pi.Name.ToLower() == columnName.ToLower() select pi;
//IEnumerable<System.Reflection.PropertyInfo> property = t.GetProperties();
foreach (PropertyInfo prpInfo in property)
{
string sProName = prpInfo.Name;
object obj = prpInfo.GetValue(info, null);
if (!Regex.IsMatch(obj.ToString(), exp[i]))
{
return "Error";
}
}
}
return "";
} public void AddRule(string ColName, string RegexExpress)
{
names.Add(ColName);
exp.Add(RegexExpress);
}
}

BusinessRules

接下来是数据实体Student,继承自BaseModel

  public class Student : BaseModel
{
public Student(string name)
{
mName = name;
}
private string mName;
public string Name
{
get
{
return mName;
}
set
{
if (mName != value)
{
mName = value;
PropertyHasChanged("Name");
}
}
}
public override void AddRule()
{
mBusinessRules.AddRule("Name", @"^-?\d+$");
} }

Student

最后是调用和效果:

  private void button1_Click(object sender, EventArgs e)
{
BindingList<Student> list = new BindingList<Student>();
Student a = new Student("张三");
list.Add(a);
Student b = new Student("张三三");
list.Add(b);
gridControl1.DataSource = list;
}

CSLA.Net学习(3)INotifyPropertyChanged和IDataErrorInfo     CSLA.Net学习(3)INotifyPropertyChanged和IDataErrorInfo

图1 初始化程序                                                                   图2修改第一行数据后,第一行错误提示消失

行头没有处理,所以一直有提示信息。

提供一个较完整的验证基类:

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text.RegularExpressions; namespace AppSurveryTools.Base
{
public abstract class EntityBase : IDataErrorInfo
{
protected BussinessRules mBussiness = null; public EntityBase()
{
mBussiness = new BussinessRules(this);
AddRules();
}
public virtual void AddRules()
{
}
public string Error
{
get { return ""; }
} public string this[string columnName]
{
get
{
string error = mBussiness.CheckRule(columnName);
return error;
}
}
}
public class BussinessRules
{
Dictionary<string, Rule> rules = new Dictionary<string, Rule>();
Object mObj = null;
private readonly Type _type;
public BussinessRules(object obj)
{
mObj = obj;
_type = mObj.GetType();
}
public void AddRules(string property, Rule rule)
{
if (!rules.ContainsKey(property))
{
rules.Add(property, rule);
}
}
public string CheckRule(string columnName)
{
if (rules.ContainsKey(columnName))
{
Rule rule = rules[columnName];
PropertyInfo[] properties = _type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo prpInfo in properties)
{
if (prpInfo.Name == columnName)
{
object obj = prpInfo.GetValue(mObj, null);
if (obj==null)
{
return "";
}
if (rule.RuleType == RuleTypes.RegexExpression)
{
if (!Regex.IsMatch(obj.ToString(), rule.RegexExpression))
{
return rule.ErrorText;
}
}
else if (rule.RuleType == RuleTypes.StringRequire)
{
if (string.IsNullOrEmpty(obj.ToString()))
{
return rule.ErrorText;
}
} }
}
}
return "";
}
public void RemoveRule(string property)
{
if (rules.ContainsKey(property))
{
rules.Remove(property);
}
}
}
public enum RuleTypes
{
RegexExpression = ,
Int32Require = ,
DoubleRequire = ,
DataRequire = ,
StringRequire =
}
public class Rule
{
public RuleTypes RuleType { get; set; }
public string ErrorText { get; set; }
public string RegexExpression { get; set; }
/// <summary>
/// 验证规则
/// </summary>
/// <param name="typeRule">验证类型</param>
/// <param name="error">提示信息</param>
/// <param name="expression">表达式</param>
public Rule(RuleTypes typeRule, string error, string expression)
{
if (typeRule == RuleTypes.RegexExpression)
{
if (!string.IsNullOrEmpty(expression))
{
RegexExpression = expression;
}
}
RuleType = typeRule;
ErrorText = error;
} public string CheckRule(string RegexExpression)
{
return "";
}
}
}

调用方法:

继承基类EntityBase,重载方法AddRules()

 public override void AddRules()
{
string express = "^([-]?(\\d|[1-8]\\d)[°](\\d|[0-5]\\d)['](\\d|[0-5]\\d)(\\.\\d+)?[\"]?[NS]?$)";
mBussiness.AddRules("WGS84B", new Rule(RuleTypes.RegexExpression, "请输入正确的纬度数据", express));
string express2 = "^([-]?(\\d|[1-9]\\d|1[0-7]\\d)[°](\\d|[0-5]\\d)['](\\d|[0-5]\\d)(\\.\\d+)?[\"]?[EW]?$)";
mBussiness.AddRules("WGS84L", new Rule(RuleTypes.RegexExpression, "请输入正确的经度数据", express2));
base.AddRules();
}

补充:类似的介绍http://blog.csdn.net/t673afa/article/details/6066278

CSLA.Net学习(3)INotifyPropertyChanged和IDataErrorInfo的更多相关文章

  1. CSLA&period;Net学习(2)

    采用CSLA.net 2.1.4.0版本的书写方式: using System; using System.ComponentModel; using Csla.Validation; using S ...

  2. CSLA框架的codesmith模板改造

    一直有关注CSLA框架,最近闲来无事,折腾了下,在最新的r3054版本基础上修改了一些东西,以备自己用,有兴趣的园友可以下载共同研究 1.添加了默认的授权规则 如果是列表对象则生成列表权限,User的 ...

  3. 《Dotnet9》系列-FluentValidation在C&num; WPF中的应用

    时间如流水,只能流去不流回! 点赞再看,养成习惯,这是您给我创作的动力! 本文 Dotnet9 https://dotnet9.com 已收录,站长乐于分享dotnet相关技术,比如Winform.W ...

  4. FluentValidation在C&num; WPF中的应用

    原文:FluentValidation在C# WPF中的应用 一.简介 介绍FluentValidation的文章不少,零度编程的介绍我引用下:FluentValidation 是一个基于 .NET ...

  5. WPF学习总结1:INotifyPropertyChanged接口的作用

    在代码中经常见到这个接口,它里面有什么?它的作用是什么?它和依赖属性有什么关系? 下面就来总结回答这三个问题. 1.这个INotifyPropertyChanged接口里就一个PropertyChan ...

  6. winform &plus; INotifyPropertyChanged &plus; IDataErrorInfo &plus; ErrorProvider实现自动验证功能

    一个简单的Demo.百度下载链接:http://pan.baidu.com/s/1sj4oM2h 话不多说,上代码. 1.实体类定义: class Student : INotifyPropertyC ...

  7. WPF学习笔记:(二)数据绑定模式与INotifyPropertyChanged接口

    数据绑定模式共有四种:OneTime.OneWay.OneWayToSource和TwoWay,默认是TwoWay.一般来说,完成数据绑定要有三个要点:目标属性是依赖属性.绑定设置和实现了INotif ...

  8. 【2016-10-24】【坚持学习】【Day11】【WPF】【MVVM】

    今天学习wpf的mvvm 人家说,APS.NET ===>MVC WPF===>MVVM 用WPF不用mvvm的话,不如用winform... 哈哈,题外话. 定义: MVVM: WPF的 ...

  9. Caliburn&period;Micro学习笔记&lpar;四&rpar;----IHandle&lt&semi;T&gt&semi;实现多语言功能

    Caliburn.Micro学习笔记目录 说一下IHandle<T>实现多语言功能 因为Caliburn.Micro是基于MvvM的UI与codebehind分离, binding可以是双 ...

随机推荐

  1. Freemarker判断是否为空

    1.判断对象是否为空 freemarker中显示某对象使用${name}. 但如果name为null,freemarker就会报错.如果需要判断对象是否为空: <#if name??> - ...

  2. C&plus;&plus;基本语法

    一.static成员变量和static成员函数 1.普通成员变量每个对象有各自的一份,而静态成员变量一共就一份,为所有对象共享 2.普通成员函数必须具体作用于某个对象,而静态成员函数并不具体作用于某个 ...

  3. MIME Sniffing

    Abstract: The web.config file does not include the required header to mitigate MIME sniffing attacks ...

  4. java--UDP屏幕广播代码

    1.发送端的代码 这里广播的地址只写了一个 package com.udp.broadcast; import java.awt.Robot; import java.awt.image.Buffer ...

  5. Ubuntu 14&period;04 启用休眠

    Ubuntu 14.04 启用休眠 Ubuntu 14.04 默认不启用关机菜单中的休眠选项.前提是要有swap分区(网上查询,未验证是否一定需要.PS:swap要不小于物理内存)不过首先最好还是确认 ...

  6. linux学习笔记之进程间通信

    一.基础知识. 1:进程通信基础(interProcess Communication, IPC):管道,FIFO(命名管道),XSI IPC,POSIX 信号量. 2:管道. 1,缺陷. 1)部分系 ...

  7. TCPDump 抓Loopback数据包

    编写网络程序必备截包工具, unix下面自带tcpdump, linux就不用说了.用于排查网络程序的bug,命令行如何使用请百度谷歌.分析包推荐wireshark,可视化非常方便.一般都是在非Win ...

  8. JS和Flash&lpar;AS&rpar;相互调用

    <!DOCTYPE html> <html> <head> <title>swf</title> <meta charset=&quo ...

  9. Zabbix 3&period;0 部署监控 &lbrack;二&rsqb;

    一.添加监控主机及设置   1.创建主机 Agent可以干一些SNMP无法干的事情,例如自定义监控项 snmp相关文章:http://www.abcdocker.com/abcdocker/1376  ...

  10. 移动端雪碧图sprite的实现

    移动端适配的时候,通常是用rem作为长宽单位,因此,在不同的设备下,元素的实际宽高(px)是不一样的,如果是单张图片作为为背景图片的时候,最为方便,只要设置背景图片的属性background-size ...