Asp.net自定义控件开发任我行(7)-注册自定义事件
摘要
前面我们已经把嵌入资源讲完了,不知道大家有没有得到收益,本章主要讲自定义事件,也就是给TextBox注册一个点击事件.
引言
不知道道上的朋友有没有注意到TextBox控件没有点击事件,就连网上非常火爆的Devexpress重写的AspxTextBox控件也没有点击事件,需要触发点击事件的时候,每次都需要用JS来做手脚,但如果某些操作涉及到页面回发(PostBack)呢?这时我就需要把TextBox扩展一下,给TextBox注册一个Click回发事件。
内容
大家都知道Button可以点击,ImageButton可以点击,他们之所以可以点击,是因为他们实现了IPostBackEventHandler接口,此接口用于处理Click事件回发。
1.继承IPostBackEventHandler接口
2.声明Click事件,base.Events其实是一个EventHandlerList事件链表,可以动态的添加和移除事件。
private static readonly object EventClick = new object();//键值对象,指明点击事件,名称随便取
[Description("点击文本框时发生"), Category("Action")]
public event EventHandler Click
{
add
{
base.Events.AddHandler(EventClick, value);
}
remove
{
base.Events.RemoveHandler(EventClick, value);
} }
3.编写事件触发方法OnClick,任何事件都会有一个触发方法,就像打架一样,是有导火线的。
protected virtual void OnClick(EventArgs e)
{
EventHandler handler = (EventHandler)base.Events[EventClick];
if (handler != null)
{
handler(this, e);
}
}
这里通过EventHandler handler = (EventHandler)base.Events[EventClick],从链表中取出上面声明好的Click事件。如果这个导火线不为空,则触发事件。
4.显式实现IPostBackEventHandler接口,this.OnClick(new EventArgs())可以写成EventArgs.Empty
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
{
this.OnClick(new EventArgs());
}
我们看看EventArgs这个类底层的东西,由下面的代码,我们可以清晰的了解到EventArgs.Empty和new EventArgs()是等价的。
namespace System
{
using System.Runtime.InteropServices; [Serializable, ComVisible(true), __DynamicallyInvokable]
public class EventArgs
{
[__DynamicallyInvokable]
public static readonly EventArgs Empty = new EventArgs();
}
}
那么页面类(客户端)到底通过什么手段产生回发的呢?
5.我们页面类中有一个方法GetPostBackEventReference(Control c)通过这个方法产生回发,并与服务器通信,开始另一个页面生命周期,记住每个回发,都是一个页面生命周,所谓的页面生命周期其实就是浏览器发送一个请求到服务器端,服务器端接收到请求后进行处理(19个委托通信管道),并将控件重新呈现到浏览器上。现在,我们来修改OnPreRender方法,调用GetPostBackEventReference方法。
protected override void OnPreRender(EventArgs e)
{ base.OnPreRender(e);
//如果文件已经被加载了,就不用重复加载
if (!this.Page.ClientScript.IsClientScriptIncludeRegistered(this.GetType(),"XYB.Controls.JS.dropDwon.js"))
{
#region 加载嵌入资源.css文件
//加载嵌入资源.css文件
string cssHref = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "XYB.Controls.CSS.dropDwon.css");
string cssLink = string.Format("<link href='{0}' rel='stylesheet' type='text/css' />", cssHref);
LiteralControl litLink = new LiteralControl(cssLink);
litLink.ID = "XYB_Controls_dropDwonCss";
this.Page.Header.Controls.Add(litLink);
#endregion
//加载嵌入资源.js文件
this.Page.ClientScript.RegisterClientScriptResource(this.GetType(), "XYB.Controls.JS.dropDwon.js");
// this.Attributes["onclick"] = "dropDwonClick()";//给文本框注册点击事件 //调用GetPostBackEventReference方法,产生页面回发。
this.Attributes["onclick"] = this.Page.GetPostBackEventReference(this); }
}
6.重新生成,TextEditUI.aspx页面修改为
<XYB:DropDwonCheckList ID="DropDwonCheckList1" runat="server"
onclick="DropDwonCheckList1_Click"></XYB:DropDwonCheckList>
7.TextEditUI.aspx.cs页面修改为
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls; namespace XYB.UI
{
public partial class TextEditUI : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void DropDwonCheckList1_Click(object sender, EventArgs e)
{
ClientScript.RegisterClientScriptBlock(this.GetType(),"","alert('我点击了,并产生了回发!!')",true);
}
}
}
8.运行看一下效果。注意画戏线的地方,没点击之前,和点击之后的不同

由此我们可以100%断定产生了回发,还有我们点击文本框时,下拉框没有出来,由此也可以断定页面回发,重新开始了一个生命周期,其实我们的文本框是显示出来了,只是进行回发的时候,下拉框默认是隐藏的,所以最后呈现的时候文本框又被隐藏掉了,整个过程那么快,不是火眼金是看到不效果的。解决办法就是在DropDwonCheckList.cs类里修改代码,添加属性DropDwonDisplay记录下拉框Display状态,那些逻辑代码我在这里不想写,我本章着重讲注册事件,现在可以说大功告成,那点逻辑代码留给大家发挥。
我们其实可以不用注册Click事件的,我们编程的理念是能不产生回发的,就尽量避免回发,回发的代价太大。为了后期的工作进行下去,我们还是用js操作下拉吧,把OnPreRender方法还原,其实就修改了onclick属性,不过此时Click事件还在,只是不会吧触发而已,可以留在那里,也可以删掉或者注释掉。
protected override void OnPreRender(EventArgs e)
{ base.OnPreRender(e);
//如果文件已经被加载了,就不用重复加载
if (!this.Page.ClientScript.IsClientScriptIncludeRegistered(this.GetType(),"XYB.Controls.JS.dropDwon.js"))
{
#region 加载嵌入资源.css文件
//加载嵌入资源.css文件
string cssHref = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "XYB.Controls.CSS.dropDwon.css");
string cssLink = string.Format("<link href='{0}' rel='stylesheet' type='text/css' />", cssHref);
LiteralControl litLink = new LiteralControl(cssLink);
litLink.ID = "XYB_Controls_dropDwonCss";
this.Page.Header.Controls.Add(litLink);
#endregion
//加载嵌入资源.js文件
this.Page.ClientScript.RegisterClientScriptResource(this.GetType(), "XYB.Controls.JS.dropDwon.js");
this.Attributes["onclick"] = "dropDwonClick()";//给文本框注册点击事件 //调用GetPostBackEventReference方法,产生页面回发。
//this.Attributes["onclick"] = this.Page.GetPostBackEventReference(this);
}
}
运行再来看效果、看看,没有产生回发吧
下集预告
绑定数据集,当绑定数据集的时候,自动生成CheckItem,也就是下拉的选项
Asp.net自定义控件开发任我行(7)-注册自定义事件的更多相关文章
- Asp.net自定义控件开发任我行(8)-数据集绑定
摘要 已经有好几天没有写博客了,今天继续,前几天写到了注册自定义事件,今天我们来讲数据集绑定. 先把运行效果截个图给大家看,让大家心里也有个底.(大家要从第一章开始看起,我们每一章都是接着前面没做完的 ...
- Asp.net自定义控件开发任我行(附1)-属性一览众山小
元数据属性应用于服务器控件及其成员,从而提供由设计工具.ASP.NET 页分析器.ASP.NET 运行库以及公共语言运行库使用的信息.当页开发人员在可视化设计器中使用控件时,设计时属性能改进开发人员的 ...
- Asp.net自定义控件开发任我行(4)-ViewState保存控件状态
摘要 上一篇我们实现了下拉框的效果,此章的目的主要是保存控件属性状态 内容 我们先来看一个例子,后台代码不变,我们只改UI页面的代码,先在页面上拖放两个控件,一个是我们现在要开发的这个控件,另一个是按 ...
- Asp.net自定义控件开发任我行(3)-Render
摘要 上一篇我们讲到了自定义标签TagPrefix用法,此篇我们来讲一下控件的呈现,主要是呈现下拉框 内容 呈现的方法有,Render,RenderControl,RenderChildren,这三个 ...
- Asp.net自定义控件开发任我行(2)-TagPrefix标签
摘要 前面我们已经做了一个最简单的TextBox的马甲,此篇文章,我们来讲讲自定义控件的标签.大家可能看到了上一篇中拖放进来的代码是 <cc1:TextEdit ID="TextEdi ...
- Asp.net自定义控件开发任我行(1)-笑傲江湖
1.引言 参加工作5个月了,来到一家小公司,有几只老鸟带我,但不是我公司的,几个礼拜才来一次.来到公司做的第一个项目是web项目,里面有很多的重复代码,页面代码都是千篇一律,你这人也太水了吧,垃圾代码 ...
- Asp.net自定义控件开发任我行(6)-嵌入资源下
摘要 上一章,我们讲了嵌入.css文件,这一章,我们来讲一下嵌入.js文件,也顺带一个嵌入Image文件 内容 我们前面的几章,一运行,下拉框就显示出来了,但是DropDwonList的下拉框是被隐藏 ...
- Asp.net自定义控件开发任我行(5)-嵌入资源上
摘要 上一篇我们讲了VitwState保存控件状态,此章我们来讲讲嵌入css文件,js文件,嵌入Image文件我也一笔带过. 内容 随着我的控件的完善,我们目标控件DropDwonCheckList最 ...
- asp.net微信开发第三篇----自定义会话管理
和微信用户的沟通少不了,总觉得看起来微信官网后台管理中的会话回复消息有点呆板,所以我这里就自定义了一个会话管理功能,最终效果图如下: 因为我试使用富文本文件CKEDITOR来进行编写,你看到稳中可能会 ...
随机推荐
- 命令行启动mysql服务
在<计算机网络>课程中曾学过net命令,可以用于启动后台服务.在mysql中,net命令用于启动后台服务器进程mysqld,即后台服务. 不过,如果在普通用户模式下net start my ...
- Elasticsearch-2.3 (OpenLogic CentOS 7.2)
平台: CentOS 类型: 虚拟机镜像 软件包: elasticsearch-2.3 application server basic software big data elasticsearch ...
- C++编写字符串类CNString,该类有默认构造函数、类的拷贝函数、类的析构函数及运算符重载
编码实现字符串类CNString,该类有默认构造函数.类的拷贝函数.类的析构函数及运算符重载,需实现以下“=”运算符.“+”运算.“[]”运算符.“<”运算符及“>”运算符及“==”运算符 ...
- office密匙
office 2010 VYBBJ-TRJPB-QFQRF-QFT4D-H3GVB 6QFDX-PYH2G-PPYFD-C7RJM-BBKQ8 BDD3G-XM7FB-BD2HM-YK63V-VQFD ...
- MVC+Nhibernate+jquery+easyui递归实现多级菜单
1.新建访问的控制器动作返回视图,在视图中使用easyui的treegrid插件来得到后台得到的json数据显示多级菜单 public ActionResult Menu() { return Vie ...
- LeetCode Number of 1 Bits 计算1的个数
题意: 提供一个无符号32位整型uint32_t变量n,返回其二进制形式的1的个数. 思路: 考察二进制的特性,设有k个1,则复杂度为O(k).考虑将当前的数n和n-1做按位与,就会将n的最后一个1去 ...
- 转: ZigBee/Z-Stack CC2530实现低功耗运行的配置简介
转: ZigBee/Z-Stack CC2530实现低功耗运行的配置简介http://bbs.elecfans.com/jishu_914377_1_1.html(出处: 中国电子技术论坛) 设备支持 ...
- 自行解决12306页面显示异常的问题(长城宽带下WWW。12306无法正常使用)
前二天突然发现家里所用的长城宽带的www.12306.cn无法正常显示,点击余票查询或者车票预订均打不开,加载时间非常长,现象好似CSS等资源文件未载入成功(如图所示)更换chrome.firefox ...
- [Rails学习之路]初识Ruby(一)
Ruby是一门动态的.强类型的.纯面向对象的编程语言.它和Python非常相似,但比Python面向对象更加彻底.使用更加灵活.语法更加复杂.也更为有趣. 抛开做事情到底应该有多少种方法这个问题,我相 ...
- 理解MVC 框架
前言:很多前端开发者面临着这样的问题,在项目开发中承担的工作越来越多,后端要做的越来越少,需要的技术棧越来越多,经常有人问你个技术是你完全不会的,对自己的职业生涯越来越怀疑.从前认为HTML+CSS+ ...