用户控件之间的ASP.NET事件委派

在ASP.NET页面上提供以下控件层次结构:

    • HeaderControl( 用户控件
      • TitleControl( 服务器控件
    • TabsControl( 用户控件
    • 其他控件

我正在尝试在TitleControl中引发一个事件(或一些通知),它会冒泡到Page级别。 然后,我想(可选) 在Page codebehind注册一个事件处理程序,它将采用EventArgs并修改上面示例中的TabsControl。 需要注意的重要一点是,这个设计允许我将这些控件放到任何页面中,并在事件处理程序连线时使整个系统无缝地工作。 该解决方案不应该涉及对FindControl()的调用,因为它成为一个强大的关联。 如果在包含的页面中没有定义处理程序,则事件仍由TitleControl引发但不处理。

我的基本目标是使用基于事件的编程,以便我可以将用户控件彼此分离。 TitleControl中的事件仅在某些情况下引发,这似乎是(在我的脑海中)首选方法。 但是,我似乎无法找到一种干净利落的方法。

以下是我的(差)尝试:

  1. 使用HttpContext.Current.Items

    将EventArgs添加到TitleControl上的Items集合中,并在TabsControl上将其拾取。 这可行,但由于两个控件之间的连接不明显,因此从根本上难以破译。

  2. 使用reflection

    而不是传递事件,直接在TitleControl中查找容器页面上的函数,如: Page.GetType().GetMethod("TabControlHandler").Invoke(Page, EventArgs); 这将起作用,但方法名称必须是一个常量,所有Page实例必须逐字定义。

我确信我过度思考这个问题并且必须有一个更漂亮的解决方案使用委托,但我似乎无法想到它。 有什么想法吗?

为了使每个控件可重用并与其他控件分离,我总是采用这种方法:每个容器将知道它包含一层深度的控件,而不是包含它的容器。 要进行沟通,您在使用事件时是正确的。 这提供了您的抽象层,并使您的所有控件都可重用。

话虽这么说,让我们来看看你的例子。 你的TitleControl不包含任何东西,所以它所做的只是火灾事件。

您的HeaderControl引用您的TitleControl并处理它的事件。 如果它没有完全处理你的TitleControl的事件,那么让它声明并触发它自己的事件 ,并传递原始发送者和事件args。

在您的页面级别,您的页面将处理您的HeaderControl的事件。 由于您的页面也是TabsControl的容器, TabsControl在您的HeaderControl事件的事件处理程序内调用TabsControl的公共方法,并传入冒泡的EventArg信息。

基本上,使用事件来冒泡,并使用公共方法或属性来推倒事物。

你想沿着这些方向做点什么吗?

您可以让Page实现一个包含事件的接口。 然后让选项卡控件查看页面是否实现了所需的界面。 如果它确实然后连接到事件。

错过了关于标题控制的部分。 标题控件还必须通过接口方法使页面自己知道。

然后,您可以在某个时刻(可能是加载事件)挂钩事件。 这当然只有在加载事件之前添加到页面的控件才有效。

HeaderControl可以公开TabsControl消耗的事件。 我之前回答过类似的问题 (附上一个示例项目)。