• 摘要

  前面我们已经把嵌入资源讲完了,不知道大家有没有得到收益,本章主要讲自定义事件,也就是给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,也就是下拉的选项

最新文章

  1. java project中 xml文件路径问题
  2. Java学习——连接数据库
  3. 栈的C++实现(数组)——创建-push-pop-top-清空栈-处理栈
  4. WPF 之 style文件的引用
  5. iOS 开发 NSLog调试小技巧
  6. php如何实现上传图片文件,并替换
  7. ubuntu下30天自制操作系统还在继续学习中
  8. Django模板-模板标签
  9. Intellij IDEA中使用Protobuf的正确姿势
  10. (python走过的坑)OpenCV中错误opencv-3.3.1\modules\highgui\src\window.cpp:339: error: (-215) size.width&gt;0 &amp;&amp; size.height&gt;0 in function cv::imshow
  11. SpringMVC MongoDB之“基本文档查询(Query、BasicQuery)”
  12. Two Sum LT1
  13. ThreadLocal MDC
  14. C_Learning (1)
  15. Cent OS 常用配置命令
  16. Android 将APK文件安装到AVD中并分析其界面结构
  17. fsck命令详解
  18. js 参数传递
  19. JS中的 ES6新类型iterable
  20. ElasticSearch深入搜索

热门文章

  1. vue实现选中列表功能
  2. 使用HTML5 canvas做地图(1)基础知识
  3. System Center Configuration Manager 2016 必要条件准备篇(Part1)
  4. WIN10+Ubuntu14.04 双系统 ubuntu无法有线上网的问题
  5. java Vamei快速教程02 方法和数据成员
  6. 部署git服务器(Windows Server 2008)
  7. swift 命名空间实现的设计思考:extension YKKit where Base == String
  8. Tarjan在图论中的应用(二)——用Tarjan来求割点与割边
  9. 5.1 Object类型
  10. Windows下配置Jmeter环境变量