复合控件和事件(5)——你Call我应

上一篇复合控件和事件(4)——移花接木
先征求个题目吧,这个名字越来越难起了,暂时就先名为《你Call我应》吧。有好的建议记得留言给我~
上一篇提到了“移花接木”之术,原理就是简单地把自己的订阅过程交给别人,也可以称之为“代购”吧。
我们知道我们经常在事件的写法中包含OnEventName的方法(用On打头算是一个约定吧)。它是一个函数,它被调用后它的内容将被执行。找一个经典的写法进行引述吧:

None.gif          protected   virtual   void  OnControlTextChanged(ControlEventArgs e)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
if (ControlTextChanged != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                ControlTextChanged(
this, e);
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

这段代码是本节示例中我写的关于事件处理程序的部分,其中virtual并不是必须的,ControlTextChanged 是我们定义的事件,看看调用OnControlTextChanged后我们都做了什么呢?
1、首先判断事件是否为空,如果不为空执行步骤2
2、通过事件委托,执行被订阅到事件的事件处理程序(通常这些事件处理程序就是我们在aspx页面中通过属性面板添加的那些事件处理程序(但不表示仅仅aspx中可以如此使用,任何地方显式或隐式使用了事件订阅语法,将事件处理程序订阅给事件的所有此类事件处理程序都将被执行,执行顺序可以类似“先进先出”))
3、事件处理程序被唤醒,依次执行相应事件处理程序(似乎目的达到了!exciting!)
假设我们的控件已经完成了,(想像一下)现在向页面中添加了我们控件,并添加事件处理程序,并订阅它(asp2.0中这个过程已经对您相对更透明了,参见复合控件和事件(3)——事件基础中的相关内容),我们把事件处理程序订阅到我们自己定义的事件上,运行我们的程序,激活事件(本示例中继续以下拉列表框来演示,这里的事件就是“下拉框中的文字变化”),我们实际上触发的是子控件(这里是下拉框,这个下拉框是包含在我们的控件中的一个private DropDownList ddl;)的相应事件,只是这时候它们的名字被我们起的刚好近似罢了。因此这时候激活的是子控件的事件处理程序。聪明的读者一定想到了解决办法:
1、提供一个事件处理程序,并将其订阅给子控件;
2、如果有数据参数的,则将参数进行传递
3、在事件处理程序中执行我们复合控件的事件的相关事件处理程序(上文中一直在提的OnEventName函数)

因此我们有如下代码:

 1 ExpandedBlockStart.gif ContractedBlock.gif          /**/ /// <summary>
 2InBlock.gif        /// 创建并添加子控件
 3ExpandedBlockEnd.gif        /// </summary>

 4 None.gif          protected   virtual   void  CreateControlHierarchy()
 5 ExpandedBlockStart.gifContractedBlock.gif         dot.gif {
 6InBlock.gif            this.ddl = new DropDownList();
 7InBlock.gif            this.ddl.TextChanged += new EventHandler(ddl_TextChanged);
 8InBlock.gif            this.Controls.Add(ddl);
 9ExpandedBlockEnd.gif        }

10 None.gif
11 None.gif         private   void  ddl_TextChanged( object  sender, EventArgs e)
12 ExpandedBlockStart.gifContractedBlock.gif         dot.gif {
13InBlock.gif            ControlEventArgs cea = new ControlEventArgs();
14InBlock.gif            cea.Message = "ControlTextChanged!";
15InBlock.gif            OnControlTextChanged(cea);
16ExpandedBlockEnd.gif        }

其中第7行做到了步骤1,第13-14行做到了第2步,第15行做到了第3步。
其实以上只是一些必要步骤,你还能做的事更多了,因为程序是因为执行了OnEventName的函数才执行了你在外部写的事件处理程序,这样的话,这里可以被理解成是一个执行程序的Driver,那么你可以在这里写下自己的运算逻辑,比如这里的第14行,当然写死了可能不太好,那你外部定义一个比如作者名之类的再通过配置文件反射进来也是个不错的选择,另外你可以让一个下拉事件同时执行多个事件,这样你在外部如果定义了三个事件处理程序,并希望它们会在事件激发(下拉框值变化)的时候执行多项事件从处理程序,也是可以的,只要在这里写上多个OnEventName就可以了,甚至你可以在这里调用工厂来执行不同的事件处理程序等,不过至于意义有多大,就得看你的应用场景了。
这一些特点在上一篇中所涉及的移花接木中则无法实现,本文中所提的方法不但可以满足需求,还能移花接木之上有所突破。

CompositeControl5.cs
ContractedBlock.gif ExpandedBlockStart.gif
None.gifusing System;
None.gif
using System.Web.UI;
None.gif
using System.Web.UI.WebControls;
None.gif
using System.ComponentModel;
None.gif
None.gif
namespace ComponentWebControls
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
//添加元数据可以使其显示在工具箱中
InBlock.gif
    [ToolboxData("<{0}:CompositeControl5 runat=\"server\" />")]
InBlock.gif    
public class CompositeControl5 : CompositeControl
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private DropDownList ddl;
InBlock.gif                
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 构造函数,为本示例提供了数据源
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public CompositeControl5()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            EnsureChildControls();
InBlock.gif            ddl.DataSource 
= GetData();
InBlock.gif            ddl.DataBind();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public bool AutoPostBack
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                EnsureChildControls();
InBlock.gif                
return this.ddl.AutoPostBack;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                EnsureChildControls();
InBlock.gif                
this.ddl.AutoPostBack = value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 定义ControlTextChanged事件
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        [Category("ControlTextChanged"), Description("ControlTextChanged")]
InBlock.gif        
public event ControlEventHandler ControlTextChanged;
InBlock.gif        
protected virtual void OnControlTextChanged(ControlEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (ControlTextChanged != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                ControlTextChanged(
this, e);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 由 ASP.NET 页面框架调用,以通知使用基于合成的实现的服务器控件
InBlock.gif        
/// 创建它们包含的任何子控件,以便为回发或呈现做准备。 
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        protected override void CreateChildControls()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//从当前服务器控件的 ControlCollection 对象中移除所有控件。 
InBlock.gif
            Controls.Clear();
InBlock.gif            CreateControlHierarchy();
InBlock.gif            
//删除服务器控件的所有子控件的视图状态信息。 
InBlock.gif
            ClearChildViewState();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 创建并添加子控件
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        protected virtual void CreateControlHierarchy()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.ddl = new DropDownList();
InBlock.gif            
this.ddl.TextChanged += new EventHandler(ddl_TextChanged);
InBlock.gif            
this.Controls.Add(ddl);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private void ddl_TextChanged(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            ControlEventArgs cea 
= new ControlEventArgs();
InBlock.gif            cea.Message 
= "ControlTextChanged!";
InBlock.gif            OnControlTextChanged(cea);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private ListItemCollection GetData()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            ListItemCollection lis 
= new ListItemCollection();
InBlock.gif            lis.Add(
new ListItem("Hello world!(DDLText)A""aaa"));
InBlock.gif            lis.Add(
new ListItem("Hello world!(DDLText)B""bbb"));
InBlock.gif            lis.Add(
new ListItem("Hello world!(DDLText)C""ccc"));
InBlock.gif            lis.Add(
new ListItem("Hello world!(DDLText)D""ddd"));
InBlock.gif            
return lis;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
CompositeControl5.aspx
ContractedBlock.gif ExpandedBlockStart.gif
ExpandedBlockStart.gifContractedBlock.gif<%dot.gif@ Page Language="C#" AutoEventWireup="true" CodeBehind="CompositeControl5.aspx.cs" Inherits="WebAppTestControls.CompositeControl5" %>
None.gif
ExpandedBlockStart.gifContractedBlock.gif
<%dot.gif@ Register Assembly="ComponentWebControls" Namespace="ComponentWebControls" TagPrefix="cc1" %>
None.gif
None.gif
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
None.gif
None.gif
<html xmlns="http://www.w3.org/1999/xhtml" >
None.gif
<head runat="server">
None.gif    
<title>CompositeControl5</title>
None.gif
</head>
None.gif
<body>
None.gif    
<form id="form1" runat="server">
None.gif    
<div>
None.gif        
<cc1:CompositeControl5 ID="CompositeControl5_1" runat="server" OnControlTextChanged="CompositeControl5_1_ControlTextChanged">
None.gif        
</cc1:CompositeControl5>
None.gif    
None.gif    
</div>
None.gif    
</form>
None.gif
</body>
None.gif
</html>
None.gif
CompostieControl5.aspx.cs
ContractedBlock.gif ExpandedBlockStart.gif
None.gifusing System;
None.gif
using System.Data;
None.gif
using System.Configuration;
None.gif
using System.Collections;
None.gif
using System.Web;
None.gif
using System.Web.Security;
None.gif
using System.Web.UI;
None.gif
using System.Web.UI.WebControls;
None.gif
using System.Web.UI.WebControls.WebParts;
None.gif
using System.Web.UI.HtmlControls;
None.gif
None.gif
namespace WebAppTestControls
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
public partial class CompositeControl5 : System.Web.UI.Page
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
protected void Page_Load(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (!IsPostBack)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this.CompositeControl5_1.AutoPostBack = true;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
protected void CompositeControl5_1_ControlTextChanged(object sender, ComponentWebControls.ControlEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.Response.Write(e.Message);
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
CompositeControl5.aspx.designer.cs
ContractedBlock.gif ExpandedBlockStart.gif
None.gif//------------------------------------------------------------------------------
None.gif
// <auto-generated>
None.gif
//     此代码由工具生成。
None.gif
//     运行库版本:2.0.50727.1318
None.gif
//
None.gif
//     对此文件的更改可能会导致不正确的行为,并且如果
None.gif
//     重新生成代码,这些更改将会丢失。
None.gif
// </auto-generated>
None.gif
//------------------------------------------------------------------------------
None.gif

ExpandedBlockStart.gifContractedBlock.gif
namespace WebAppTestControls dot.gif{
InBlock.gif    
InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// CompositeControl5 类。
InBlock.gif    
/// </summary>
InBlock.gif    
/// <remarks>
InBlock.gif    
/// 自动生成的类。
ExpandedSubBlockEnd.gif    
/// </remarks>

ExpandedSubBlockStart.gifContractedSubBlock.gif    public partial class CompositeControl5 dot.gif{
InBlock.gif        
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// form1 控件。
InBlock.gif        
/// </summary>
InBlock.gif        
/// <remarks>
InBlock.gif        
/// 自动生成的字段。
InBlock.gif        
/// 要进行修改,请将字段声明从设计器文件移到代码隐藏文件。
ExpandedSubBlockEnd.gif        
/// </remarks>

InBlock.gif        protected global::System.Web.UI.HtmlControls.HtmlForm form1;
InBlock.gif        
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// CompositeControl5_1 控件。
InBlock.gif        
/// </summary>
InBlock.gif        
/// <remarks>
InBlock.gif        
/// 自动生成的字段。
InBlock.gif        
/// 要进行修改,请将字段声明从设计器文件移到代码隐藏文件。
ExpandedSubBlockEnd.gif        
/// </remarks>

InBlock.gif        protected global::ComponentWebControls.CompositeControl5 CompositeControl5_1;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值