【问题标题】:Event Bubbling From Web User Controls in ASP.NET来自 ASP.NET 中的 Web 用户控件的事件冒泡
【发布时间】:2012-07-01 18:38:22
【问题描述】:

我有两个用户控件 - PageDefault.aspx 中的 UserControl1.ascx 和 UserControl2.ascx:

如何使用事件冒泡从 UserControl2.ascx 调用方法 (GetLabelText() in UserControl1.ascx)?

这是我的示例代码 - 当我点击按钮 (UserControl2Button1 in UserControl1.ascx) - 我想调用方法 GetLabelText() from UserControl2.ascx - 使用事件冒泡。

PageDefault.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="PageDefault.aspx.cs" Inherits="TelerikAjaxEvents.PageDefault" %>
<%@ Register TagPrefix="uc" TagName="UserControl1" Src="~/UserControl1.ascx" %>
<%@ Register TagPrefix="uc" TagName="UserControl2" Src="~/UserControl2.ascx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Page Default</title>
</head>
<body>
    <form id="form1" runat="server">
        UserControl1:
        <uc:UserControl1 ID="UserControl1" runat="server" />

        UserControl2:
        <uc:UserControl2 ID="UserControl2" runat="server" />

    </form>
</body>
</html>

UserControl1.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="UserControl1.ascx.cs" Inherits="TelerikAjaxEvents.UserControl1" %>
<asp:Label ID="UserControl1Label1" runat="server"></asp:Label>

UserControl1.ascx.cs

public partial class UserControl1 : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        public void GetLabelText() 
        {
            UserControl1Label1.Text = "Text is Visible";
        }
    }

UserControl2.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="UserControl2.ascx.cs" Inherits="TelerikAjaxEvents.UserControl2" %>
<asp:Button ID="UserControl2Button1" runat="server" Text="Send" 
    onclick="UserControl2Button1_Click" />

UserControl2.ascx.cs

public partial class UserControl2 : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void UserControl2Button1_Click(object sender, EventArgs e)
        {
            //Call method from UserControl1 (GetLabelText()) - Show Label text - USING BUBBLE EVENT
        }
    }

【问题讨论】:

  • ASP.NET 中没有“事件冒泡”机制。您必须通过在 UserControl2 上添加一个新事件来公开该事件。

标签: asp.net user-controls event-bubbling


【解决方案1】:

有很多方法可以解决这个问题。 Mark 的回答暗示了使用 System.Web.UI.Control 基本控件的内置功能部分进行的经典事件冒泡。但是,公开您自己的事件、绑定到它并通过控制层次结构冒泡事件是一个简单的练习。有关在 ASP.NET 中使用 BubbleEvent 的更多详细信息,请阅读以下内容。请记住,这两篇 MSDN 文章都是为 .NET 1.1 编写的

Bubbling an Event

Event Bubbling Control Sample

K。 Scott Allen 在他的帖子中很好地展示了“事件冒泡”实现的样子:Event Bubbling From Web User Controls in ASP.NET (C#) 。请参阅以下对您的示例的修改以获得灵感。

带有 GetLabelText() 的 UserControl1

public partial class UserControl1 : System.Web.UI.UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    public void GetLabelText() 
    {
        UserControl1Label1.Text = "Text is Visible";
    }
}

带有公开的 BubbleClick 事件处理程序的 UserControl2,调用者可以订阅。

public partial class UserControl2 : System.Web.UI.UserControl
{
    protected Button UserControl2Button1;

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    public event EventHandler BubbleClick;

    protected void OnBubbleClick(EventArgs e)
    {
        if(BubbleClick != null)
        {
            BubbleClick(this, e);
        }
    }      
    protected void UserControl2Button1_Click(object sender, EventArgs e)
    {
        // do some stuff
        OnBubbleClick(e);
    }
}

PageDefault 订阅 UserControl2 的 BubbleClick 事件处理程序并执行 UserControl1.GetLabelText()

public partial class PageDefault : WebPage
{
    UserControl1 userControl1;
    UserControl2 userControl2;

    protected void Page_Load(object sender, EventArgs e)
    {
        UserControl2.BubbleClick += RootBubbleClickHandler;
    }

    protected void RootBubbleClickHandler(object sender, EventArgs e)
    {
        if (sender is UserControl2)
        {
            // subscribe UserControl1 to UserControl2 click event and do something
            userControl1.GetLabelText();
        }

        // check for other controls with "BubbleClicks"         
    }
}

【讨论】:

  • 我的意思是这样的:odetocode.com/code/94.aspx 这个例子怎么用?
  • 我明白了。我已更新答案以使用本文中讨论的模式。这是否更符合您的想法?
【解决方案2】:

事件冒泡是 ASP.NET WebForms 中一个鲜为人知的概念。它确实存在(并且被大多数数据绑定控件使用),但经常被误认为是“在用户控件中实现事件”这一更简单的概念(就像 K Scott Allen 所做的那样)。

事件冒泡的核心是事件在控制层次结构中向上传播,直到它被处理或到达根。这允许处理程序代码的一些集中化。它是使用 Control.RaiseBubbleEvent 和 Control.OnBubbleEvent 方法实现的。主要用例是带有很多子控件的控件(想想Repeaters、ListViews 等)。不是订阅每个单独的控件,Repeater 将它们全部捕获在它的 OnBubbleEvent 中并为它们引发一个 ItemCommandEvent。

如果您真的想使用事件冒泡(与 K. Scott 的示例相反),它看起来像:

class Page {
    override bool OnBubbleEvent(object sender, EventArgs e) {
         var btn = sender as Button;
         if (btn == null) return false;

         // You may want to do further checking that the source is what you want
         // You could use CommandEventArgs to do this
         this.uc1.GetLabelText();
         return true;
    }
}

事件的顺序是这样的:

- Button Clicked
- Button RaiseBubbleEvent
- UserControl OnBubbleEvent returns false (default, since you didn't override)
- Page OnBubbleEvent

【讨论】:

    【解决方案3】:

    您能否尝试在 PageDefault.aspx 上将 UserControl1 声明为公共属性(例如“UserControl1”),然后在 UserControl2 中使用 Parent.Page.UserControl1.GetLabelText()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-23
      • 2013-09-20
      • 1970-01-01
      • 1970-01-01
      • 2012-08-09
      • 1970-01-01
      • 1970-01-01
      • 2011-08-05
      相关资源
      最近更新 更多