验证方式,   通过继承 IDataErrorInfo接口 和 DataAnnotations 解释标记语言而实现,

为了能在WPF上通用,所了也要继承属性更改通知接口INotifyPropertyChanged

实际INotifyPropertyChanged接口

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel; namespace ClassLibrary1
{
public class NotifyPropertyChanged : INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
} public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
}

验证核心类   继承 IDataErrorInfo和INotifyPropertyChanged的实现类

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Reflection; namespace ClassLibrary1
{
/// <summary>
/// 验证类和更改通知类
/// System.ComponentModel.DataAnnotations;
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class ValidationEntity<T> : NotifyPropertyChanged,IDataErrorInfo
{
public string Error
{
get { return null; }
} public string this[string columnName]
{
get
{
return ValidateProperty(columnName);
}
} /// <summary>
/// 验证是否通过
/// </summary>
/// <param name="errors">错误信息 ErrorMessage 值提取</param>
/// <returns></returns>
public bool Valid(ref Dictionary<string, string> errors)
{
bool result = true;
Type t = this.GetType();
PropertyInfo[] PropertyInfo = t.GetProperties();
try
{
foreach (PropertyInfo pi in PropertyInfo)
{
string name = pi.Name;
if (name == "Error" || name=="Item")
continue;
object value1 = pi.GetValue(this, null);
Dictionary<string, string> propertyErrors = new Dictionary<string, string>();
if (!IsPropertyValid(value1, name, ref propertyErrors))
{
result = false;
foreach (var item in propertyErrors)
{
if (!errors.ContainsKey(item.Key))
{
errors.Add(item.Key, item.Value);
}
}
}
}
}
catch (Exception ex)
{
string aaaa = ex.Message;
}
return result;
} /// <summary>
/// 验证属性值是否合格
/// </summary>
/// <param name="propertyName">属性名</param>
/// <returns></returns>
private string ValidateProperty(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
return string.Empty;
object obj = this;
var targetType = obj.GetType();
if (targetType != typeof(T))
{
TypeDescriptor.AddProviderTransparent(
new AssociatedMetadataTypeTypeDescriptionProvider(targetType, typeof(T)), targetType);
}
var propertyValue = targetType.GetProperty(propertyName).GetValue(obj, null);
var validationContext = new ValidationContext(obj, null, null);
validationContext.MemberName = propertyName;
var validationResults = new List<ValidationResult>();
Validator.TryValidateProperty(propertyValue, validationContext, validationResults);
if (validationResults.Count > )
{
return validationResults.First().ErrorMessage;
}
return string.Empty;
} /// <summary>
/// 验证属性值
/// </summary>
/// <param name="propertyValue">属性值</param>
/// <param name="propertyName">属性名</param>
/// <param name="errors">错误信息</param>
/// <returns></returns>
private bool IsPropertyValid(object propertyValue, string propertyName, ref Dictionary<string, string> errors)
{
object obj = this;
TypeDescriptor.AddProviderTransparent(
new AssociatedMetadataTypeTypeDescriptionProvider(obj.GetType(), typeof(T)), obj.GetType());
var validationContext = new ValidationContext(obj, null, null);
validationContext.MemberName = propertyName;
var validationResults = new List<ValidationResult>();
Validator.TryValidateProperty(propertyValue, validationContext, validationResults);
if (validationResults.Count > && errors == null)
errors = new Dictionary<string, string>(validationResults.Count);
foreach (var validationResult in validationResults)
{
if (!errors.ContainsKey(validationResult.MemberNames.First()))
errors.Add(validationResult.MemberNames.First(), validationResult.ErrorMessage);
}
if (validationResults.Count > )
return false;
else
return true;
} /// <summary>
/// 辅助方法,把消息转成字符串
/// </summary>
/// <param name="errors">消息</param>
/// <returns></returns>
public string ErrorToString(Dictionary<string, string> errors)
{
if (errors == null || errors.Count == )
return "";
StringBuilder str = new StringBuilder();
foreach (var item in errors)
{
str.Append(item.Value);
str.Append(Environment.NewLine);
}
str.Remove(str.Length - , );
return str.ToString();
} }
}

下面是分别在mvc,wpf,winform下的使用实例

C# 通用验证类 支持 WPF,MVC,Winform的更多相关文章

  1. c#后台输出javascript语句和一些通用验证的类

    大家在用MVC的时候,经常会用到MODEL层的验证或者是正则表达式,我这边看到了一篇不错的文章,转载过来http://blog.csdn.net/accpxcb/article/details/311 ...

  2. 做一个牛XX的身份证号验证类(支持15位和18位)

    原文:做一个牛XX的身份证号验证类(支持15位和18位) #region 是否合法的中国身份证号码 protected bool IsChineseID() { if (str.Length == 1 ...

  3. C#操作SqlServer MySql Oracle通用帮助类Db_Helper_DG(默认支持数据库读写分离、查询结果实体映射ORM)

    [前言] 作为一款成熟的面向对象高级编程语言,C#在ADO.Net的支持上已然是做的很成熟,我们可以方便地调用ADO.Net操作各类关系型数据库,在使用了多年的Sql_Helper_DG后,由于项目需 ...

  4. WPF与WinForm的抉择

    微软曾经对WPF(代号Avalon)抱很大的期望——新一代的华丽用户界面平台,一统Web应用和桌面应用,Flash杀手,尽管微软口头上不承认.几年下来,WPF确实实现了当初的预期的大部分功能,但离称霸 ...

  5. 通用窗口类 Inventory Pro 2.1.2 Demo1(下)

    本篇想总结的是Inventory Pro中通用窗口的具体实现,但还是要强调下该插件的重点还是装备系统而不是通用窗口系统,所以这里提到的通用窗口类其实是通用装备窗口类(其实该插件中也有非装备窗口比如No ...

  6. WPF与Winform的选择

    最近公司计划对ERP系统全面升级,现有的ERP是简单的bs架构系统打算改版成cs.平时如自己写一些工具,小应用都是用winform就足够.但是界面总是很难看,据了解WPF在这一方面会强一些.因为之前对 ...

  7. MVC 插件化框架支持原生MVC的Area和路由特性

    .NET MVC 插件化框架支持原生MVC的Area和路由特性 前面开放的源码只是简单的Plugin的实现,支持了插件的热插拔,最近晚上偶然想到,原生的MVC提供Areas和RouteAtrribut ...

  8. Mvc_后端通用验证

    namespace Web.Mvc.Extensions { #region 验证基类 /// <summary> /// 通用验证基类 /// </summary> publ ...

  9. CYQ.Data 支持WPF相关的数据控件绑定(2013-08-09)

    事件的结果 经过多天的思考及忙碌的开发及测试,CYQ.Data 终于在UI上全面支持WPF,至此,CYQ.Data 已经可以方便支持wpf的开发,同时,框架仍保留最低.net framework2.0 ...

随机推荐

  1. 老罗学习MVC之旅:MVC组件分析

    2System.Web.Mvc V 4.0.0.0 组件分析 2.1 Routing组件(路由选择) Routing的作用就是负责分析Url   Action的要求• 必须是一个公有方法• 必须返回A ...

  2. No connection string named '***' could be found in the application config file

    Code-First时更新数据库遇到妖孽问题“No connection string named '***' could be found in the application config fil ...

  3. HDU 4107 Gangster Segment Tree线段树

    这道题也有点新意,就是须要记录最小值段和最大值段,然后成段更新这个段,而不用没点去更新,达到提快速度的目的. 本题过的人非常少,由于大部分都超时了,我严格依照线段树的方法去写.一開始竟然也超时. 然后 ...

  4. 多个App间传递数据

    平台:Android两个App:A,B:需求:在A中点击一个按钮后,启动B并把数据从A传递到B: 代码: App A: MainActivity.java中添加: Button btn2 = (But ...

  5. UDP"打洞"原理

    1. NAT分类 根据Stun协议(RFC3489),NAT大致分为下面四类 1) Full Cone 这种NAT内部的机器A连接过外网机器C后,NAT会打开一个端口.然后外网的任何发到这个打开的端口 ...

  6. 使用wireshark抓取wcf生成的soap消息

    在使用wcf的时候想看下生成的soap的格式是怎样的,就想到了抓包. 平时用惯的抓包工具是需要破解,另外有时会不太好用. 于是就想起来用wireshark. 首先遇到几个问题: 1.wireshart ...

  7. javap生成的字节码

    https://www.zhihu.com/question/49470442/answer/135812845http://blog.csdn.net/tzs_1041218129

  8. Xcode 安装插件手误选择了「Skip Bundle」后需要重新允许「Load Bundle」的解决方法

    在 Mac 终端输入命令: # 这里的7.1代表 Xcode 的版本号 defaults delete com.apple.dt.Xcode DVTPlugInManagerNonApplePlugI ...

  9. 为什么要提倡“Design Pattern呢

    为什么要提倡“Design Pattern呢?根本原因是为了代码复用,增加可维护性. 那么怎么才能实现代码复用呢?面向对象有几个原则:开闭原则(Open Closed Principle,OCP).里 ...

  10. ffmpeg 中 swscale 的用法

    http://www.guguclock.com/2009/12/ffmpeg-swscale.html 如果想將某個PixelFormat轉換至另一個PixelFormat,例如,將YUV420P轉 ...