大家对如下的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通用数据验证组件的更多相关文章

  1. 自定义react数据验证组件

    我们在做前端表单提交时,经常会遇到要对表单中的数据进行校验的问题.如果用户提交的数据不合法,例如格式不正确.非数字类型.超过最大长度.是否必填项.最大值和最小值等等,我们需要在相应的地方给出提示信息. ...

  2. ASP.NET通用权限验证组件实现

    沙发(SF)通用权限验证组件 开篇 本篇介绍通用权限验证的实现代码思路,总共分为导入参数.解析XML.根据XML配置进行处理.返回结果. 代码架构图 1.   类介绍 1.SFWebPermissio ...

  3. kpvalidate开辟验证组件,通用Java Web请求服务器端数据验证组件

    小菜利用工作之余编写了一款Java小插件,主要是用来验证Web请求的数据,是在服务器端进行验证,不是简单的浏览器端验证. 小菜编写的仅仅是一款非常初级的组件而已,但小菜为它写了详细的说明文档. 简单介 ...

  4. Java实战之01Struts2-03属性封装、类型转换、数据验证

    九.封装请求正文到对象中 1.静态参数封装 在struts.xml配置文件中,给动作类注入值.调用的是setter方法. 原因:是由一个staticParams的拦截器完成注入的. 2.动态参数封装: ...

  5. 【C#】使用IExtenderProvider为控件添加扩展属性,像ToolTip那样

    申明: - 本文适用于WinForm开发 - 文中的“控件”一词是广义上的说法,泛指包括ToolStripItem.MenuItem在内单个界面元素,并不特指继承自Control类的狭义控件 用过To ...

  6. Winform开发框架之通用数据导入导出操作的事务性操作完善

    1.通用数据导入导出操作模块回顾 在我的Winfrom开发框架里面,有一个通用的导入模块,它在默默处理这把规范的Excel数据导入到不同的对象表里面,一直用它来快速完成数据导入的工作.很早在随笔< ...

  7. c#自定义ORM框架---(泛型&反射&实体类扩展属性<附带通用增、删、查、改>)

    该教材主要是运用到泛型.反射和实体类扩展属性 步骤一.建立扩展属性类 实体类扩展属性要继承Attribute基类完成 [AttributeUsage(AttributeTargets.Property ...

  8. ClownFish:比手写代码还快的通用数据访问层

    http://www.cnblogs.com/fish-li/archive/2012/07/17/ClownFish.html 阅读目录 开始 ClownFish是什么? 比手写代码还快的执行速度 ...

  9. 【原创】开发Kafka通用数据平台中间件

    开发Kafka通用数据平台中间件 (含本次项目全部代码及资源) 目录: 一. Kafka概述 二. Kafka启动命令 三.我们为什么使用Kafka 四. Kafka数据平台中间件设计及代码解析 五. ...

随机推荐

  1. 使用opencv实现自定义卷积

    对图像进行卷积是图像处理的基本操作,最近在研究图像滤波,经常要用到自定义卷积,所以实现了一下 #include "opencv2/imgproc/imgproc.hpp" #inc ...

  2. 计算机网络——DNS协议的学习与实现

    1. 主要内容 不说废话,直接进入正题.先说说本文本文的主要内容,好让你决定是否看下去: 介绍DNS是干什么的: 介绍DNS是如何工作的: 介绍DNS请求与响应的消息格式: 编程实现一个简单的DNS服 ...

  3. Mac OS平台下应用程序安装包制作工具Packages的使用介绍(补充)

    上一篇:Mac OS平台下应用程序安装包制作工具Packages的使用介绍 补充说明 上一篇文章中介绍了如何使用Packages如何创建mac下的安装包.但是这样制作出来的安装包只能安装到系统的文件路 ...

  4. MySQL数据库的安装布局

    首先我们要安装(mysql-5.0.18-win32_zip) 第一步:点击(Setup.exe) 第二步:开始安装(MySQL Server5.0版本) 1.点击(Next) 2.选Custom自定 ...

  5. loopj.com android-async-http

    loopj.com android-async-http Android异步Http客户端 用于Android的基于回调的Http客户端库   下载版本1.4.9(最新) 或者在github上fork ...

  6. java设计模式--基础思想总结--父类引用操作对象

    看设计模式的相关书籍也有一段时间了,一开始其实是抱着作为java三大框架的基础知识储备来学习的,不过到后来,才发现,在设计模式的一些准则装饰下,java的面向对象威力才真正地体现出来,后面的将会陆续地 ...

  7. nginx参数的详细说明

    #开启进程数 <=CPU数 worker_processes 1; #错误日志保存位置 #error_log logs/error.log; #error_log logs/error.log ...

  8. php生成二维码的几种方式整理及使用实例

    hp生成二维码的方式:1.google开放api:2.php类库PHP QR Code:3.libqrencode:4.QRcode Perl CGI & PHP scripts感兴趣的朋友可 ...

  9. Ruby读excel写入mysql

    安装mysql2 打开cmd: gem install mysql2 代码 require 'win32ole' require 'mysql2' class String def addslashe ...

  10. seajs模块标识命名和解析规则

    模块标识采用路径形式,但要注意与路径的区别.require.require.async的第一个参数是模块标识.而seajs.use第一个参数为文件路径. use是全局的,require是局部的.模块标 ...