第三章 为控件添加事件 后篇

前一篇文章只是简单的说了下事件,但是大家应该方法,在ASP.NET自定义控件中只是简单那么定义事件是行不

通。如果大家开发的是WinForm中的事件,之前的定义可能没有什么大的问题,只是在效率方法欠考虑而且,还是可以运行

的。

系列文章链接:

ASP.NET自定义控件组件开发 第一章 待续

ASP.NET自定义控件组件开发 第一章 第二篇 接着待续

ASP.NET自定义控件组件开发 第一章 第三篇

ASP.NET自定义控件组件开发 第二章 继承WebControl的自定义控件

ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇

ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇

ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡

ASP.NET自定义控件组件开发 第五章 模板控件开发

ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性

ASP.NET2.0组件控件开发视频 初体验

下面我们就回到ASP.NET中的事件。

大家也许看了我们之前定义的事件,确实,事件一般是那么定义的,但是那样定义事件后的,运行起来的效率不搞,

因为那样定义事件后,编译器在编译事件代码的时候,会自动的为我们加入很多多线程安全的代码,就是说,虽然我们只是

定义几行代码,大但是编译器为我们做了很多额外的事情,当然,这样代码的运行的效率可想而知。

在很多的时候,我们自定义控件的事件不是需要考虑多线程安全等问题的,所我们就要改变代码,使其运行的更加好,

我们就采用下面的方法:显示的申明事件:

Code
 1  
 2 //其实其实一个辅助的变量,用来做Hashtable中的”键“
 3 private static object ValidateCreditCardFormKey = new object();
 4         public event ValidateCreditCardFormEventHandler ValidateCreditCardForm
 5         {
 6             add
 7             {
 8                 Events.AddHandler(ValidateCreditCardFormKey, value);
 9             }
10             remove
11             {
12                 Events.RemoveHandler(ValidateCreditCardFormKey, value);
13             }
14         }
15 
16        
17         protected void OnValidateCreditCardForm(ValidateCreditCardFormEventArgs args)
18         {
19             ValidateCreditCardFormEventHandler handler = Events[ValidateCreditCardFormKey]
20                                                                         as ValidateCreditCardFormEventHandler;
21             if (handler != null)
22                 handler(this, args);
23         }

注意:其实就我们之前定义的事件的代码而言,编译器在在编译我们的代码的时候,也是编译成了上面的形式而且还额外

的加上了一些安全的控制代码,这里,我们现在不要编译器生成,而是我们自己写出来,效率就高了。

还有就是:如果一个事件在事件列表(是一个hashtable)已经注册了,当页面上有两个相同我们自定义控件,我的控件

的事件也只是在注册一次,效率也高了。

到这里一个事件就定义好了。

现在做的事情就是要触发事件。即,点击“提交”按钮,就触发。

我们先了理解一下流程:

点击“提交”,整个页面就向服务器提交了,之后就开始了页面的生命周期。

1.对页面进行解析,将原来页面中的源,如<asp:....></asp>这样的标记解析成相应的html代码,当

把页面解析完之后,页面在服务器就是html的样式了。(我这里说的很粗略,没有必要说的那么详细)。

2.解析后的页面就开始检查,刚才是哪个控件引发的服务器回传,即,是点击了哪个按钮后,整个页面向服

务器提交的,我们这里就是那个“提交”按钮。

3.解析后的页面检查“提交”按钮的name是否和控件(CreditCardForm)的name相同,如果相同。再检

查控件 CreditCardForm实现了IPostBackEventHandler接口,如果实现了,就引发我们之前定义的事件。

这样,我们的控件就和真正的服务器控件没有两样了。

(注意:上面的第3点:我们要按钮的name和CreditCardForm的name一样,这里的name我们无法用自己手动来设置他们

的一样,因为CreditCardForm的名字是有页面来设置的,页面将其设置为:this.UniqueID,所以我们只能将按钮的名字设置

为this.UniqueID,这样就可以了),所以我们要重写CreditCardForm5的一些属性:

Code
1  protected override string SubmitButtonName
2         {
3             get
4             {
5                 return this.UniqueID ;
6             }
7         }

还有,每一次页面提交给服务器后,解析页面的this.UniqueID都不一样。而且,如果在页面中同时有两个CreditCardForm,我们也要保证两个控件的其他控件,如输入框等等的name也不一样,所以要分别重写name。

Code
 1 protected override string PaymentMethodListName
 2         {
 3             get
 4             {
 5                 return this.UniqueID + ":PaymentMethod";
 6             }
 7         }
 8 
 9         protected override string CreditCardNoTextName
10         {
11             get
12             {
13                 return this.UniqueID + ":CreditCardNo";
14             }
15         }
16 
17         protected override string CardholderNameTextName
18         {
19             get
20             {
21                 return this.UniqueID + ":CardholderName";
22             }
23         }
24 
25         protected override string MonthListName
26         {
27             get
28             {
29                 return this.UniqueID +":Month";
30             }
31         }
32 
33         protected override string YearListName
34         {
35             get
36             {
37                 return this.UniqueID + ":Year";
38             }
39         }

这里以后,下面我们就只要实现IPostBackEventHandler接口,就可以调用我们的事件了,实现IPostBackEventHandler接口,其实只有一个方法。而且也很简单,代码:

Code
 1  
 2 
 3 //大家看看我们只是将之前的事件通知代码移到了这里。
 4 void IPostBackEventHandler.RaisePostBackEvent(string args)
 5         {
 6             ValidateCreditCardFormEventArgs ve = new ValidateCreditCardFormEventArgs(
 7                 PaymentMethodText, CreditCardNoText, CardholderNameText, ExpirationDateText);
 8 
 9             OnValidateCreditCardForm(ve);
10         }

这样以后,我们的控件就可以引发服务器回传了,即,当你点击“提交”按钮时,我们的浏览器的状态栏下面就有刷新的

进度条了。

注意,还有一个问题啊,我们确实能够使得我们的控件向服务器提交信息,但是服务器怎么来得到我们的提交的信息

呢?

并不是我们把信息向服务器提交后,就什么都不管了,然后服务器就”很听话的“进行验证。不是这样的,起码我们还要

告诉服务器,我们提交了哪些要被验证的信息。

那么服务器这样接受到我们的信息,,很简单,只要实现一个接口就可以了--IPostBackDataHandler。

接口有两个方法,第一个就是LoadPostData方法,就是来获取我们的信息,并且判断我们这次提交的信息和上次有变化

没有。

上面的方法返回一个布尔的值,如果返回true,就自动的调用下一个方法RaisePostDataChangedEvent,

大家可以根据方法的英文看到他们的作用。

这里我们只是讲下LoadPostData方法,方法的完成写法是这样的:

Code
1 bool LoadPostData(string postDataKey, NameValueCollection values)
2 {

4 }

看见方法不要害怕,方法的参数,前一个参数,我们不要管,只要看看后面的参数就可以了。

我们的信息的提交,都是在相应的输入框,下拉框中写好了,传给服务器的,其实是以:键值对,传了的.

键:就是我们输入框等的名字,name

值:就是输入的值。

其实NameValueCollection就是一个哈希表,来存放键值对的。

我们之前的所有输入的信息被包含成了一个NameValueCollection传到服务器,然后服务器就通过对应的“键”(name)来获取值,然后验证。

代码如下:

Code
 1  bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection values)
 2         {
 3             string paymentMethod = values[PaymentMethodListName] == "0" ? "Master" : "Visa";
 4             if (paymentMethod != PaymentMethodText)
 5             {
 6                 PaymentMethod = paymentMethod;
 7                 hasPaymentMethodChanged = true;
 8             }
 9 
10             string creditCardNo = values[CreditCardNoTextName];
11             if (creditCardNo != CreditCardNoText)
12             {
13                 CreditCardNoText = creditCardNo;
14                 hasCreditCardNoChanged = true;
15             }
16 
17             string cardholderName = values[CardholderNameTextName];
18             if (cardholderName != CardholderNameText)
19             {
20                 CardholderNameText = cardholderName;
21                 hasCardholderNameChanged = true;
22             }
23 
24             int month = int.Parse(values[MonthListName]);
25             int year=int.Parse (values [YearListName ]);
26             DateTime expirationDate=new DateTime (year ,month,10);
27             if(expirationDate !=ExpirationDateText )
28             {
29                 ExpirationDateText =expirationDate ;
30                 hasExpirationDateChanged =true ;
31             }
32 
33 
34             if(!string.IsNullOrEmpty (values [SubmitButtonName ]))
35                 Page.RegisterRequiresRaiseEvent (this);
36 
37             return hasExpirationDateChanged||
38                 hasCreditCardNoChanged ||
39                 hasPaymentMethodChanged ||
40                 hasCardholderNameChanged ;
41 
42         }

这样,我们整个控件就写完了,不知道大家懂了没:有问题回复!完整代码如下:

Code
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Text;
  4 using System.Web;
  5 using System.Web.UI;
  6 using System.Web.UI.WebControls;
  7 using System.Collections ;
  8 
  9 using System.Collections.Specialized ;
 10 
 11 namespace CreditCardForm
 12 {
 13     public class CreditCardForm6:CreditCardForm5 ,IPostBackEventHandler,IPostBackDataHandler
 14     {
 15         #region override name
 16         protected override string PaymentMethodListName
 17         {
 18             get
 19             {
 20                 return this.UniqueID + ":PaymentMethod";
 21             }
 22         }
 23 
 24         protected override string CreditCardNoTextName
 25         {
 26             get
 27             {
 28                 return this.UniqueID + ":CreditCardNo";
 29             }
 30         }
 31 
 32         protected override string CardholderNameTextName
 33         {
 34             get
 35             {
 36                 return this.UniqueID + ":CardholderName";
 37             }
 38         }
 39 
 40         protected override string MonthListName
 41         {
 42             get
 43             {
 44                 return this.UniqueID +":Month";
 45             }
 46         }
 47 
 48         protected override string YearListName
 49         {
 50             get
 51             {
 52                 return this.UniqueID + ":Year";
 53             }
 54         }
 55 
 56         protected override string SubmitButtonName
 57         {
 58             get
 59             {
 60                 return this.UniqueID ;
 61             }
 62         }
 63         #endregion
 64         #region prorerty
 65 
 66         public string PaymentMethodText
 67         {
 68             get
 69             {
 70                 return ViewState["PaymentMethod"] != null ? (string)ViewState["PaymentMethod"] : string.Empty ;
 71             }
 72             set
 73             {
 74                 ViewState["PaymentMethod"] = value;
 75             }
 76         }
 77 
 78 
 79         public string CreditCardNoText
 80         {
 81             get
 82             {
 83                 return ViewState["CreditCardNo"] != null ? (string)ViewState["CreditCardNo"] : string.Empty;
 84             }
 85             set
 86             {
 87                 ViewState["CreditCardNo"] = value;
 88             }
 89         }
 90 
 91         public string CardholderNameText
 92         {
 93             get
 94             {
 95                 return ViewState["CardholderName"] != null ? (string)ViewState["CardholderName"] : string.Empty;
 96             }
 97             set
 98             {
 99                 ViewState["CardholderName"] = value;
100             }
101         }
102 
103         public DateTime ExpirationDateText
104         {
105             get
106             {
107                 return ViewState["ExpirationDate"] != null ? (DateTime)ViewState["ExpirationDate"] : DateTime.Now;
108             }
109             set
110             {
111                 ViewState["ExpirationDate"] = value;
112             }
113         }
114 
115 
116         #endregion
117 
118         #region events
119         private static object ValidateCreditCardFormKey = new object();
120         public event ValidateCreditCardFormEventHandler ValidateCreditCardForm
121         {
122             add
123             {
124                 Events.AddHandler(ValidateCreditCardFormKey, value);
125             }
126             remove
127             {
128                 Events.RemoveHandler(ValidateCreditCardFormKey, value);
129             }
130         }
131 
132        
133         protected void OnValidateCreditCardForm(ValidateCreditCardFormEventArgs args)
134         {
135             ValidateCreditCardFormEventHandler handler = Events[ValidateCreditCardFormKey]
136                                                                         as ValidateCreditCardFormEventHandler;
137             if (handler != null)
138                 handler(this, args);
139         }
140 
141         #endregion
142         void IPostBackEventHandler.RaisePostBackEvent(string args)
143         {
144             ValidateCreditCardFormEventArgs ve = new ValidateCreditCardFormEventArgs(
145                 PaymentMethodText, CreditCardNoText, CardholderNameText, ExpirationDateText);
146 
147             OnValidateCreditCardForm(ve);
148         }
149 
150         private bool hasPaymentMethodChanged;
151         private bool hasCreditCardNoChanged;
152         private bool hasCardholderNameChanged;
153         private bool hasExpirationDateChanged;
154 
155         bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection values)
156         {
157             string paymentMethod = values[PaymentMethodListName] == "0" ? "Master" : "Visa";
158             if (paymentMethod != PaymentMethodText)
159             {
160                 PaymentMethod = paymentMethod;
161                 hasPaymentMethodChanged = true;
162             }
163 
164             string creditCardNo = values[CreditCardNoTextName];
165             if (creditCardNo != CreditCardNoText)
166             {
167                 CreditCardNoText = creditCardNo;
168                 hasCreditCardNoChanged = true;
169             }
170 
171             string cardholderName = values[CardholderNameTextName];
172             if (cardholderName != CardholderNameText)
173             {
174                 CardholderNameText = cardholderName;
175                 hasCardholderNameChanged = true;
176             }
177 
178             int month = int.Parse(values[MonthListName]);
179             int year=int.Parse (values [YearListName ]);
180             DateTime expirationDate=new DateTime (year ,month,10);
181             if(expirationDate !=ExpirationDateText )
182             {
183                 ExpirationDateText =expirationDate ;
184                 hasExpirationDateChanged =true ;
185             }
186 
187 
188             if(!string.IsNullOrEmpty (values [SubmitButtonName ]))
189                 Page.RegisterRequiresRaiseEvent (this);
190 
191             return hasExpirationDateChanged||
192                 hasCreditCardNoChanged ||
193                 hasPaymentMethodChanged ||
194                 hasCardholderNameChanged ;
195 
196         }
197 
198         void IPostBackDataHandler.RaisePostDataChangedEvent()
199         {
200             bool hasChanged;
201             hasChanged = hasCardholderNameChanged ||
202                 hasCreditCardNoChanged ||
203                 hasPaymentMethodChanged ||
204                 hasExpirationDateChanged;
205 
206             if (hasChanged)
207             {
208 
209                 ValidateCreditCardFormEventArgs args = new ValidateCreditCardFormEventArgs(
210                     PaymentMethod, CreditCardNoText, CardholderNameText, ExpirationDateText);
211 
212                 OnValidateCreditCardForm(args);
213             }
214         }
215 
216     }
217 }
218 

ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇相关推荐

  1. ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇

    第三章 为控件添加事件 好了,我们之前以前开发一个控件.而且也添加了属性,开发也很规范,但是那个控件还差最后一点:添加事件. 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.N ...

  2. ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

    第四章 组合控件开发CompositeControl 大家好,今天我们来实现一个自定义的控件,之前我们已经知道了,要开发自定义的控件一般继承三个基 类:Control,WebControl,还有一个就 ...

  3. ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性

    深入讲解控件的属性持久化(一) 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接着待续 ASP.NET自定义控件组件开发 第一章 第 ...

  4. ASP.NET自定义控件组件开发 第一章 第二篇 接着待续

    ASP.NET自定义控件组件开发 第一章 第二篇 接着待续 ASP.NET自定义控件组件开发 第一章 第二篇 接着待续 很感谢大家给我的第一篇ASP.NET控件开发的支持!在写这些之前,我也看了一些例 ...

  5. 走向.NET架构设计—第三章—分层设计,初涉架构(后篇)

    走向.NET架构设计-第三章-分层设计,初涉架构(后篇) 前言:本篇主要是接着前两篇文章继续讲述! 本篇的议题如下: 4. 数据访问层设计 5. 显示层设计 6. UI层设计   4.  数据访问层设 ...

  6. python winform开发_c#教程之.Net WInform开发笔记(三)谈谈自制控件(自定

    末日这天写篇博客吧,既然没来,那就纪念一下. 这次谈谈自制控件,也就是自定义控件,先上图,再说 1.扩展OpenFileDialog,在OpenFileDialog中添加各种文件(.txt,.jpg, ...

  7. Android第一行代码——第三章:控件的使用方法5A-00-1A-C4-8C-55(2009+jjy)

    标题:这章主要学习如何控件的使用方法 1 TextView. 创建activity_main.xml中的代码 代码如下: <?xml version="1.0" encodi ...

  8. 卜若的代码笔记-一周速通LayaAir-第三章:给Button添加事件

    1.事件绑定函数: this.button.on(Laya.Event.CLICK, this, f12); 需要注意的是,第2个参数通常填this,第三个参数则是你绑定的执行函数. 声明执行函数的方 ...

  9. Qt (高仿Visio)流程图组件开发(三) 图元基类如何定义,流程图多种图元类型实现

    文章目录 本系列目录 前言 一.图元基类的定义 1.图元信息基类结构体 2.图元位置 3.父子对象关系 二.自定义图元实现 1.自定义图元基类(FlowchartGraphicsItem)与Qt原生图 ...

最新文章

  1. MoviePy - 中文文档2-快速上手-MoviePy-预览
  2. DDD-EF-数据仓储
  3. pthread中如何追踪stack over flow
  4. C++:C++语言入门级基础知识考察点回顾之函数、结构体和类
  5. python中值滤波去除椒盐噪声_python 中值滤波,椒盐去噪,图片增强实例
  6. scip 练习2.18
  7. 深夜,我偷听到程序员要对session下手.......
  8. [leedcode 52] N-Queens II
  9. windows 2008 r2 AD域控服务器部署
  10. ARM Cortex-M0 原理与应用实践
  11. sendEmail invalid SSL_version at SSL.pm
  12. java逻辑删除代码_MybatisPlus实现逻辑删除功能
  13. 搜狗泛站群之搜狗批量提交软件
  14. 跨时钟域脉冲信号处理——脉冲同步器
  15. PM应具备的规划技巧-顾客价值管理
  16. 当学术沾染名利,约翰伯努利对儿子的嫉恨,影响数学界几十年发展
  17. Unity3D - 使用天空盒子(Using Skyboxes)
  18. 基于QT的在线打字练习软件助手(C/S模型)
  19. 【Lintcode】1718. Minimize Malware Spread
  20. jdk源码分析,Java视频全套

热门文章

  1. 核心编程9 文件和文件的输入输出 (os模块)
  2. MySQL服务安装和可视化工具安装
  3. 【机器学习】谷歌的速成课程(二)
  4. html的body内标签之图片及表格
  5. BZOJ 2956 模积和(分块)
  6. JAVA第一次实验 ——实验楼
  7. MySQL errno: 145 错误修复
  8. 深度linux安装spotify,如何在 Linux 上使用 snap 安装 Spotify(声破天)
  9. html灵活响应 图片设置,jQuery轻量级响应式图片轮播插件ResponsiveSlides.js(仅1kb)
  10. 【小项目关键技术四】液晶显示屏