WinForm TextBox自定义扩展方法数据验证

时间:2023-02-26 20:33:59

本文转载:http://www.cnblogs.com/gis-crazy/archive/2013/03/17/2964132.html

查看公司项目代码时,存在这样一个问题:winform界面上有很多信息填写,提交后台服务器更新,但数据的合法验证及值的转换却不太敢恭维,一堆的if判断和转换,便想着是否能扩展个方法出来,琢磨出个思路,记录下来与大家共同探讨,有不对的地方还请大家指正。

设计思路:
    1. 由于大部分从TextBox控件中获取数据值,可以扩展个泛型方法出来,直接根据转换后的数据类型获得值,类似这样,
      var value = this.txtSample.GetValue<int>();

    2. 可以传入一个委托用来处理转换失败的操作,并重载此方法,提供一个默认的操作。

  好,下面开工:
    1. 创建TextBox类型的扩展方法
      引用MSDN的解释:扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。 对于用 C# 和 Visual Basic 编写的客户端代码,调用扩展方法与调用在类型中实际定义的方法之间没有明显的差异。
      扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。 它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。 仅当您使用using 指令将命名空间显式导入到源代码中之后,扩展方法才位于范围中。
      注意:扩展方法是在非嵌套、非泛型静态类内部定义的

    2. 由于转换类型未知,但为值类型,故采用泛型方法设计,并加上strut泛型约束,由于允许自定义处理转换失败时的操作,故传入一个Action委托来实现,如下:

WinForm TextBox自定义扩展方法数据验证
public static TResult GetValue<TResult>(this TextBox textBox, Action<TextBox> failed)
where TResult : struct
{
var type = typeof(TResult);
var method = type.GetMethod("TryParse", new Type[] { typeof(string), type.MakeByRefType() });
var parameters = new object[] { textBox.Text, default(TResult) }; // 若转换失败,执行failed
if (!(bool)method.Invoke(null, parameters))
{
failed(textBox);
throw new InvalidCastException("输入值格式不正确,请检查输入值。");
} return (TResult)parameters[1];
}
WinForm TextBox自定义扩展方法数据验证

       这里采用反射机制来调用类型的T.TryParse(string param, out T value),例如Int32.TryParse(string param,out Int32 value)等,需要注意的是:
       (1). GetMethod()方法,必须传入合适的参数(要反射的方法的签名)来确定方法唯一,例如碰到重载这种情况(比较常见),否则返回值为null,方法的签名中,若参数带有ref 或out 关键字,则Type类型需要加上.MakeByRefType(),如上。
       (2). 得到唯一的方法实例后,可以传入相应的参数,调用Invoke方法来实现方法的调用,MethodInfo.Invoke(object obj, object[] parameters)方法第一个参数为反射调用该方法的对象,如果为静态方法(比如本例),可以传入null,第二个参数为方法的参数,顺序必须与方法签名一致。
       (3). 方法参数中带有ref和out关键字,获得该值通过参数数组来获得。如本例中:parameters[1]

    3. 定义转换失败操作的委托
      C#内置封装的委托有两种,Action和Func委托,并有很多的重载版本,参数可以有十多个,所以不用担心参数问题。其中Action委托无返回值,属于Void类型,Func委托具有返回值,如Func<T,TResult>,在Linq操作中比较常见,在该例中,无返回值的必要,故采用Action委托,由于需要处理转换失败的操作,故将TextBox作为该委托的参数里进行处理,如代码所示,当转换失败时进行处理:   
                    // 若转换失败,执行failed
                    if (!(bool)method.Invoke(null, parameters))
                          failed(textBox);
      在此简单介绍下委托:委托其实是一个类型,通过反编译工具可以看出来,当构造委托时传入一个方法,其实会隐形的传入两个参数(target,methodPtr),target参数为调用该方法的实例,若静态方法,则为null,methodPtr为传入方法的内存地址(在元数据中存贮该信息),faild(textBox)表面看不太好理解,为什么一个对象后面带一个参数,其实C#编译器为我们做了很多工作,在这里实质为faild.Invoke(textBox),这样看还好理解委托是个类型,通过faild的委托对象来调用该委托所注册的方法。

    4. 创建重载版本:
      用lambda表达式定义默认的转换失败操作,如果转换失败,则提示信息,并全部选中和定位到该输入框上。

WinForm TextBox自定义扩展方法数据验证
 public static TResult GetValue<TResult>(this TextBox textBox, bool isShowError)
where TResult : struct
{
return GetValue<TResult>(textBox, p =>
{
if (isShowError)
{
p.Focus();
p.SelectAll();
MessageBox.Show("输入值格式不正确,请重新输入!",
"提示--值类型:" + typeof(TResult).Name,
MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
});
}
WinForm TextBox自定义扩展方法数据验证
WinForm TextBox自定义扩展方法数据验证
///默认版本,调用上个重载方法

public static TResult GetValue<TResult>(this TextBox textBox)
where TResult : struct
{
return GetValue<TResult>(textBox, true);
}
WinForm TextBox自定义扩展方法数据验证

    5. 实验测试:
      新建winform程序,界面如图所示:

WinForm TextBox自定义扩展方法数据验证

      后台代码:

WinForm TextBox自定义扩展方法数据验证
private void btnConvert_Click(object sender, EventArgs e)
{
try
{
var intValue = txtInt.GetValue<int>();
var floatValue = txtFloat.GetValue<float>();
var dateTimeValue = txtDateTime.GetValue<DateTime>();
var doubleValue = txtDouble.GetValue<double>();
}
catch (Exception) { }
}
WinForm TextBox自定义扩展方法数据验证

如果输入值非法,则提示错误,如图所示:
                     WinForm TextBox自定义扩展方法数据验证

转载请注明出处:http://www.cnblogs.com/gis-crazy/archive/2013/03/17/2964132.html

WinForm TextBox自定义扩展方法数据验证的更多相关文章

  1. Silverlight实例教程 - 自定义扩展Validation类&comma;验证框架的总结和建议(转载)

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

  2. AbpVnext使用分布式IDistributedCache Redis缓存&lpar;自定义扩展方法&rpar;

    AbpVnext使用分布式IDistributedCache缓存from Redis(带自定义扩展方法) 我的依赖包的主要版本以及Redis依赖如下 1:添加依赖 <PackageReferen ...

  3. Jquery自定义扩展方法(二)--HTML日历控件

    一.概述 研究了上节的Jquery自定义扩展方法,自己一直想做用jquery写一个小的插件,工作中也用到了用JQuery的日历插件,自己琢磨着去造个*--HTML5手机网页日历控件,废话不多说,先看 ...

  4. Layui数据表格加入自定义扩展方法&lpar;重新渲染Render当前页数据&rpar;

    具体开发中遇到的问题如下, 数据表格的重新渲染或重新加载会导致当前操作的分页 或 配置被清空.我正在操作第5页,重新渲染后就回到了最原始第1页. 需要达到的效果是: 不调用接口,仅仅只是从table. ...

  5. Jquery自定义扩展方法(一)

    jquery是一款流行的JS框架,自定义JS方法,封装到Jquery中,调用起来也挺方便的,怎么写Jquery扩展方法那,网上翻阅了一部分代码,其实也挺简单的: 方式一: (jQuery.fn.set ...

  6. Unity中自定义扩展方法

    问题背景 在使用unity开发过程中,通常会遇到一种情况,比如说给物体重新赋值坐标的问题, Transfrom tran: ,pos_y=,pos_z=; tran.position=new Vect ...

  7. C&num; 实现和调用自定义扩展方法

    定义和调用扩展方法 定义一个静态类以包含扩展方法.该类必须对客户端代码可见. 将该扩展方法实现为静态方法,并使其至少具有与包含类相同的可见性. 该方法的第一个参数指定方法所操作的类型:该参数必须以 t ...

  8. Swift学习(二):自定义扩展方法(Extensions)

    扩展就是向一个已有的类.结构体或枚举类型添加新功能(functionality) 扩展可以 添加计算型属性和计算静态属性 定义实例方法和类型方法 提供新的构造器 定义下标 定义和使用新的嵌套类型 使一 ...

  9. MVC———用自定义扩展类实现验证

    废话少说,直接上图 →_→ NO.1 NO.2 NO.3 NO.4 NO.5 NO.6 NO.7 NO.8 NO.9 NO.10 NO.11 NO.12 NO.13 NO.14 NO.15 NO.16 ...

随机推荐

  1. R自动数据收集第一章概述——《List of World Heritage in Danger》

      导包     library(stringr) library(XML) library(maps) heritage_parsed <- htmlParse("http://en ...

  2. AI&lpar;Adobe Illustrator&rpar;简单入门——米老鼠

    成果: 步骤如下: 一.新建文档 二.选椭圆工具,在画布中间点一下,画一个100px*100px的圆,如下 三.同上,再画两个50px*50px小圆.点左上角的选择工具,点小圆中心,放好位置. 四.全 ...

  3. php--tp3&period;2引入sphinx搜索

    1.首先我们把coreseek下载好,命名为coreseek,我们找到coreseek/etc中的csft_mysql.conf修改这个配置文件 #源定义 source lemai { type    ...

  4. 【转】怎么在Foxmail回复&sol;转发时使用签名?

    原文网址:http://kf.qq.com/faq/120322fu63YV130422yABZRZ.html Foxmail回复/转发时使用签名,可通过在模版中设置签名.如下版本操作方法: 一.fo ...

  5. 自己做的网页页面导航浏览JS&sol;JQuery

    需求: 当页面是由一个巨大的表格构成时,浏览器自动会出现纵向和横向滚动条,这时用户浏览页面会出现很蛋疼的感受,那就是恶心的横向滚动条! 为了减缓这种蛋疼的感觉,我尝试做了这个导航器(不知道如何称呼), ...

  6. js--冒泡排序&lbrack;由小到大&rsqb;

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  7. lvs学习笔记

    本人身为一个网工,最近一直在工作中学习linux的相关知识.前短时间通过自查资料学习了lvs的相关内容,摘录部分整理后和大家分享,内容较多,较琐碎,望见谅!!! LVS 从Linux内核版本2.6起, ...

  8. java结合testng,利用excel做数据源的数据驱动实例

    数据驱动部分,是自动化测试常用部分,也是参数化设计的重要环节,前面分享了,mysql.yaml做数据源,那么再来分享下excel做数据驱动 思路: 先用POI读取excel.解析读取数据,返回list ...

  9. websocket采用tomcat方式,IOC类对象无法注入的解决方案

    前言 我采用的spring框架做的,主要用于IOC AOP ,spring之前采用的2.0版本.(2.0版本出错!下面有解释): 要实现websocket 实现后台主动与JSP发送数据. 具体操作 在 ...

  10. 在 Azure Resource Manager 中为虚拟机设置密钥保管库

    Note Azure 具有两种不同的部署模型,用于创建和处理资源:Resource Manager 模型和经典模型.本文介绍使用 Resource Manager 部署模型.Azure 建议对大多数新 ...