容器扩展属性 IExtenderProvider 实现WinForm通用数据验证组件
大家对如下的Tip组件使用应该不陌生,要想让窗体上的控件使用ToolTip功能,只需要拖动一个ToolTip组件到窗口,所有的控件就可以使用该功能,做信息提示。
本博文要记录的,就是通过容器扩展属性 IExtenderProvider,来实现一个数据验证组件,通过将组件拖动到窗口后,使得上面的所有控件可以实现数据验证!

设置下面两个扩展属性,即可使用组件

调用开放的验证方法public bool VerifyData(Control ct = null)后,验证样式为:

1.实现思路:
通过记录每个控件的验证规则,和相应验证提示信息,结合ErrorProvider组件,为控件实现提示信息。时间不多,直接上代码吧,看注释。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace CFW.WinFormBase.Controls
{
/// <summary>
/// 为控件提供数据验证规则扩展属性
/// </summary>
[Description("为菜单项或控件提供描述扩展属性")]
[ProvideProperty("Verify", typeof(Control))]
[ProvideProperty("VerifyMsg", typeof(Control))]
public class ControlVerify : Component, IExtenderProvider
{
/// <summary>
/// 存储所服务的控件及其验证规则
/// </summary>
readonly Dictionary<Control, Validata> dic;
/// <summary>
/// 存储所服务的控件及其验证提示信息
/// </summary>
readonly Dictionary<Control, string> msgDic;
/// <summary>
/// 错误验证提示类
/// </summary>
public ErrorProvider errTip;
/// <summary>
/// 创建一个Verify类
/// </summary>
public ControlVerify()
{
dic = new Dictionary<Control, Validata>();
msgDic = new Dictionary<Control, string>();
errTip = new ErrorProvider();
} /// <summary>
/// 数据验证
/// </summary>
/// <returns></returns>
/// <param name="ct">验证控件所在容器 null为全部</param>
public bool VerifyData(Control ct = null)
{
//errTip.Clear();
var ret = true;
foreach (var item in dic)
{
var data = item.Key.Text;//数据
var verify = item.Value;//验证规则 if (ct != null && item.Key.Parent != ct)
{
errTip.SetError(item.Key, "");
continue;
}
if (DataVali(data,verify))
{
errTip.SetError(item.Key, "");
}
else
{
string errMsg = msgDic[item.Key];
errTip.SetError(item.Key, errMsg.Length > ? errMsg : "请输入正确的数据");
ret = false;
} }
return ret;
}
/// <summary>
/// 清除验证提示
/// </summary>
public void ClearVerify()
{
errTip.Clear();
}
private bool DataVali(string data,Validata vali)
{
bool ret = false;
var _data = data.Trim();
switch (vali)
{
case Validata.无:
ret = true;
break;
case Validata.Require:
if (_data.Length > )
ret = true;
break;
case Validata.AgeValue:
if (!_data.IsNullOrEmpty() && !_data.IsMatch("^[0 - 9] + $"))
{
ret = false;
}
else
{
ret = true;
} break;
case Validata.DateValue:
ret = _data.IsMatch(@"^(\d{2}|\d{4})((0[1-9])|(1[0-2]))((0[1-9])|((1|2)[0-9])|30|31)$");
break;
case Validata.NumberValue:
ret = _data.IsMatch(@"^[0 - 9] + $");
break;
case Validata.TelValue:
ret = _data.IsPhone();
break;
case Validata.IntValue:
int parse = ;
ret = int.TryParse(_data,out parse);
break;
case Validata.IdCardValue:
ret = _data.IsIdCard();
break;
default:
break;
}
return ret;
}
/// <summary>
/// 获取菜单项描述
/// </summary>
[Description("设置验证规则")] //虽然方法为Get,但在VS中显示为“设置”才符合理解
[DefaultValue(Validata.无)]
public Validata GetVerify(Control item)
{
//从集合中取出该item的描述
Validata value;
string str;
dic.TryGetValue(item, out value);
msgDic.TryGetValue(item, out str);
return value;
} /// <summary>
/// 设置验证规则描述
/// </summary>
public void SetVerify(Control item, Validata value)
{
if (item == null) { return; } if (value == Validata.无)
{
//从集合中移除该item,并取消其相关事件绑定
dic.Remove(item);
msgDic.Remove(item);
}
else
{
//添加或更改该item的描述
dic[item] = value;//这种写法对于dic中不存在的Key,会自动添加
msgDic[item] = "";
}
} /// <summary>
/// 获取菜单项描述
/// </summary>
[Description("设置验证提示")] //虽然方法为Get,但在VS中显示为“设置”才符合理解
[DefaultValue("")]
public string GetVerifyMsg(Control item)
{
//从集合中取出该item的描述
string value;
msgDic.TryGetValue(item, out value);
return value;
} /// <summary>
/// 设置验证规则提示信息
/// </summary>
public void SetVerifyMsg(Control item, string value)
{
if (item == null) { return; } if (value == "")
{
//从集合中移除该item,并取消其相关事件绑定
msgDic.Remove(item);
}
else
{
//添加或更改该item的描述
msgDic[item] = value;//这种写法对于dic中不存在的Key,会自动添加
}
} /// <summary>
/// 是否可为某对象扩展属性
/// </summary>
public bool CanExtend(object extendee)
{
return true;
}
}
public enum Validata
{
无,
Require,
AgeValue,
DateValue,
NumberValue,
TelValue,
IntValue,
IdCardValue,
}
}
2.调用方法:
Verify.VerifyData();

容器扩展属性 IExtenderProvider 实现WinForm通用数据验证组件的更多相关文章
- 自定义react数据验证组件
我们在做前端表单提交时,经常会遇到要对表单中的数据进行校验的问题.如果用户提交的数据不合法,例如格式不正确.非数字类型.超过最大长度.是否必填项.最大值和最小值等等,我们需要在相应的地方给出提示信息. ...
- ASP.NET通用权限验证组件实现
沙发(SF)通用权限验证组件 开篇 本篇介绍通用权限验证的实现代码思路,总共分为导入参数.解析XML.根据XML配置进行处理.返回结果. 代码架构图 1. 类介绍 1.SFWebPermissio ...
- kpvalidate开辟验证组件,通用Java Web请求服务器端数据验证组件
小菜利用工作之余编写了一款Java小插件,主要是用来验证Web请求的数据,是在服务器端进行验证,不是简单的浏览器端验证. 小菜编写的仅仅是一款非常初级的组件而已,但小菜为它写了详细的说明文档. 简单介 ...
- Java实战之01Struts2-03属性封装、类型转换、数据验证
九.封装请求正文到对象中 1.静态参数封装 在struts.xml配置文件中,给动作类注入值.调用的是setter方法. 原因:是由一个staticParams的拦截器完成注入的. 2.动态参数封装: ...
- 【C#】使用IExtenderProvider为控件添加扩展属性,像ToolTip那样
申明: - 本文适用于WinForm开发 - 文中的“控件”一词是广义上的说法,泛指包括ToolStripItem.MenuItem在内单个界面元素,并不特指继承自Control类的狭义控件 用过To ...
- Winform开发框架之通用数据导入导出操作的事务性操作完善
1.通用数据导入导出操作模块回顾 在我的Winfrom开发框架里面,有一个通用的导入模块,它在默默处理这把规范的Excel数据导入到不同的对象表里面,一直用它来快速完成数据导入的工作.很早在随笔< ...
- c#自定义ORM框架---(泛型&反射&实体类扩展属性<附带通用增、删、查、改>)
该教材主要是运用到泛型.反射和实体类扩展属性 步骤一.建立扩展属性类 实体类扩展属性要继承Attribute基类完成 [AttributeUsage(AttributeTargets.Property ...
- ClownFish:比手写代码还快的通用数据访问层
http://www.cnblogs.com/fish-li/archive/2012/07/17/ClownFish.html 阅读目录 开始 ClownFish是什么? 比手写代码还快的执行速度 ...
- 【原创】开发Kafka通用数据平台中间件
开发Kafka通用数据平台中间件 (含本次项目全部代码及资源) 目录: 一. Kafka概述 二. Kafka启动命令 三.我们为什么使用Kafka 四. Kafka数据平台中间件设计及代码解析 五. ...
随机推荐
- 服务器上的Git
前面的话 如果想与他人使用,除了使用Git来完成日常工作之外,还需要一个远程的Git仓库.尽管从技术上可以从个人的仓库里推送和拉取修改内容,但并不鼓励这样做,因为一不留心就很容易弄混其他人的进度.因此 ...
- 对Qt下对话服务器客户端的总结(MyTcpServer与MyTcpClient)
在汇文培训老师给讲了这个例子.讲的挺好的 Qt编写聊天服务器与客户端主要用到下面两个类: QTcpSocket --- 处理连接的 QTcpServer --- 处理服务器,对接入进行响应,创建每个链 ...
- 第三章 PL/SQL编程
3.1 PL/SQL基础知识 3.1.1 什么是PL/SQL? PL/SQL是结合Oracle过程语言和结构化查询语言的一种扩展语言 3.1.1.1 PL/SQL体系 ...
- angular双向数据绑定
<body ng-app> //三个view都会变 <input type="text" ng-model="name" value=&quo ...
- Servlet3.0新特性(从注解配置到websocket编程)
Servlet3.0的出现是servlet史上最大的变革,其中的许多新特性大大的简化了web应用的开发,为广大劳苦的程序员减轻了压力,提高了web开发的效率.主要新特性有以下几个: 引入注解配置 支持 ...
- React Starter Kit 中文文档
最近没事又翻译了个玩意. Github上的一个Star 非常高的 React 样板程序. 由Node.js,Express,GraphQL和React构建,可选加入Redux等,并可以包含Webpac ...
- 浅析c++/java/c#三大热门编程语言的运行效率
从安全角度考虑,C#是这几中语言中最为安全的,它其中定义的相关安全机制很好的确保了系统的安全... 今天和同学们一起探讨下c++/java/c# 三大热门语言的运行效率情况,以及各自的用途. 估计有很 ...
- angularjs中常用的ng指令介绍【转载】
原文:http://www.cnblogs.com/lvdabao/p/3379659.html 一.模板中可使用的东西及表达式 模板中可以使用的东西包括以下四种: 指令(directive).ng提 ...
- bzoj2560 串珠子
Description 铭铭有n个十分漂亮的珠子和若干根颜色不同的绳子.现在铭铭想用绳子把所有的珠子连接成一个整体. 现在已知所有珠子互不相同,用整数1到n编号.对于第i个珠子和第j个珠子,可以选择不 ...
- Python:字符串的分片与索引、字符串的方法
这是关于Python的第3篇文章,主要介绍下字符串的分片与索引.字符串的方法. 字符串的分片与索引: 字符串可以用过string[X]来分片与索引.分片,简言之,就是从字符串总拿出一部分,储存在另一个 ...