您需要在控件上创建一个事件,该事件被父级订阅。有关示例,请参见
OdeToCode。
以下是为了长期保存而撰写的文章:
某些用户控件完全自包含,例如,显示当前股票行情的用户控件不需要与页面上的任何其他内容交互。其他用户控件将包含按钮进行回发。虽然可以从包含页面订阅按钮单击事件,但这样做会破坏一些面向对象的封装规则。更好的想法是在用户控件中发布事件,以允许任何感兴趣的方处理事件。
这种技术通常称为“事件冒泡”,因为事件可以继续通过层传递,从底部(用户控件)开始,可能到达顶层(页面),就像气泡在香槟杯中上升一样。
首先,让我们创建一个带有附加按钮的用户控件。
<%@ Control Language="c#" AutoEventWireup="false"
Codebehind="WebUserControl1.ascx.cs"
Inherits="aspnet.eventbubble.WebUserControl1"
TargetSchema="http://schemas.microsoft.com/intellisense/ie5"
%>
<asp:Panel id="Panel1" runat="server" Width="128px" Height="96px">
WebUserControl1
<asp:Button id="Button1" Text="Button" runat="server"/>
</asp:Panel>
用户控件的代码如下所示。
public class WebUserControl1 : System.Web.UI.UserControl
{
protected System.Web.UI.WebControls.Button Button1;
protected System.Web.UI.WebControls.Panel Panel1;
private void Page_Load(object sender, System.EventArgs e)
{
Response.Write("WebUserControl1 :: Page_Load <BR>");
}
private void Button1_Click(object sender, System.EventArgs e)
{
Response.Write("WebUserControl1 :: Begin Button1_Click <BR>");
OnBubbleClick(e);
Response.Write("WebUserControl1 :: End Button1_Click <BR>");
}
public event EventHandler BubbleClick;
protected void OnBubbleClick(EventArgs e)
{
if(BubbleClick != null)
{
BubbleClick(this, e);
}
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
}
用户控件指定了一个公共事件(BubbleClick),该事件声明了一个委托。对于任何对BubbleClick事件感兴趣的人,都可以添加一个EventHandler方法,在事件触发时执行 - 就像用户控件为Button触发Click事件添加EventHandler一样。
在OnBubbleClick事件中,我们首先检查是否有人附加到事件(BubbleClick!= null),然后通过调用BubbleClick并传递EventArgs参数以及将用户控件(this)设置为事件发送者来调用所有事件处理方法。请注意,我们还使用Response.Write来跟踪执行流程。
现在,ASPX页面可以让用户控件开始工作。
<%@ Register TagPrefix="ksa"
TagName="BubbleControl"
Src="WebUserControl1.ascx"
%>
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs"
AutoEventWireup="false" Inherits="aspnet.eventbubble.WebForm1"
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm1</title>
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<ksa:BubbleControl id="BubbleControl" runat="server" />
</form>
</body>
</HTML>
在页面的后台代码中。
public class WebForm1 : System.Web.UI.Page
{
protected WebUserControl1 BubbleControl;
private void Page_Load(object sender, System.EventArgs e)
{
Response.Write("WebForm1 :: Page_Load <BR>");
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
BubbleControl.BubbleClick += new EventHandler(WebForm1_BubbleClick);
}
#endregion
private void WebForm1_BubbleClick(object sender, EventArgs e)
{
Response.Write("WebForm1 :: WebForm1_BubbleClick from " +
sender.GetType().ToString() + "<BR>");
}
}
注意,父页面只需在InitializeComponent方法中添加事件处理程序。当我们收到事件时,我们将再次使用Reponse.Write来跟踪执行流程。
一个警告:如果任何时候事件神秘地停止工作,请检查InitializeComponent方法,以确保设计器没有删除添加事件处理程序的任何代码。