1

本质上,我在页面加载时动态添加了一个占位符。

然后我有一个复合控件添加到占位符并在运行时显示特定页面事件。复合控件有一个按钮。我有一个用于复合控件中可用按钮的公共事件处理程序,但实际上并没有直接访问页面代码中的此事件处理程序。

要显示控件,我会进行以下调用,例如:

MyControl.Create(args, new EventHandler(OnClick)); 

然后在我会的页面上protected void OnClick(object o, EventArgs args) {}

当然,当我调用create()我的事件处理程序时,我会将事件处理程序连接到复合控件的按钮单击事件。到目前为止,一切都很好。连接按钮后,按钮单击按预期返回到控件。但是,该事件永远不会返回到页面的事件处理程序。

我意识到问题是在回发时发生的。然而,尝试在 init、load 或 createchildcontrols 上连接按钮都无法保持连接到位,因此可以在页面上处理事件。我想要的是能够在运行时将事件处理程序传递给复合控件,并让复合控件在回发时正确地将事件发送回页面。

有趣的是,如果我使用自定义事件参数调用 OnBubble,我可以在页面上捕获冒泡事件。但问题是我的占位符在页面上,所以当我尝试调用MyControl.Create()UserControl 时,例如,气泡会转到页面而不是 UserControl(如预期的那样)。因此,我更喜欢声明事件处理程序而不是覆盖的原因OnBubble(UserControls 和其他声明 MyControl 的控件基本上会使它对按钮单击事件无用)。

我希望有人对这个问题有所了解。这似乎是一个有趣的问题,但除了在页面上显式声明控件并直接在标记或页面加载中连接事件之外,可能没有其他解决方案。我会考虑让按钮进行异步回调,但如果可能的话,我更愿意使用标准的 ASP.NET 事件处理。

谢谢!

添加说明:该MyControl.Create()调用实际上生成了一个事件,该事件调用了复合控件的Create()方法。这一切都很好,但值得注意的是该MyControl.Create()方法无法直接访问控件。这应该是有道理的,因为控件被添加到页面onload上而不是在标记中。

更多代码:

MyControl : CompositeControl 
{
     public event EventHandler Click;

     //I have a create method
     void Create(args, EventHandler click)
     {
          this.Click = click;
          //other processing
     }

     //then the button is wired up. I've tried in OnInit(), OnLoad()
     void CreateChildControls()
     {
           MyButton.OnClick += Click;
     }

     //if I wire up the button to a default handler I can check if
       Click is not null and send the click event onto the next handler 
     //this is where the bubble event works, but the wiring fails
} 

编辑:我尝试将事件处理程序存储在 Session 中并在回发时连接按钮是成功的。我不认为这是一种好的做法,我认为它实际上并没有达到我的目的。例如,在这种情况下,页面上的事件按预期执行,但具有非标准页面行为。例如, Response.Redirect() 会引发异常。这应该是有道理的,因为事件处理程序可能在回发期间丢失了状态信息。一些想法: 1.我是否可以创建一个与此控件相关的自定义气泡事件?这似乎是合理的,但是页面回发的问题再次让我遇到了同样的问题,即气泡应该去哪里。所以,当我调用 create() 时,我可以自动将 UserControl 注册为气泡的目的地吗?似乎很难。2. 在页面生命周期中的某个时刻,我可以在 UserControl 声明的事件处理程序上重新连接事件,以便在回发时正确调用委托?这似乎是我所缺少的。事件处理程序是在回发时创建的,但由于在 OnClick 期间未在 UserControl 中重新创建而丢失。我不希望 UserControl 必须显式地重新创建事物,而是希望子控件为 UserControl 重新创建它。这听起来像是一个简单的请求,但是如果 UserControl 不在循环中,我可能会要求不可能的事情。在页面生命周期中是否有某个点可以在 UserControl 声明的事件处理程序上重新连接事件,以便在回发时正确调用委托?这似乎是我所缺少的。事件处理程序是在回发时创建的,但由于在 OnClick 期间未在 UserControl 中重新创建而丢失。我不希望 UserControl 必须显式地重新创建事物,而是希望子控件为 UserControl 重新创建它。这听起来像是一个简单的请求,但是如果 UserControl 不在循环中,我可能会要求不可能的事情。在页面生命周期中是否有某个点可以在 UserControl 声明的事件处理程序上重新连接事件,以便在回发时正确调用委托?这似乎是我所缺少的。事件处理程序是在回发时创建的,但由于在 OnClick 期间未在 UserControl 中重新创建而丢失。我不希望 UserControl 必须显式地重新创建事物,而是希望子控件为 UserControl 重新创建它。这听起来像是一个简单的请求,但是如果 UserControl 不在循环中,我可能会要求不可能的事情。但希望子控件为 UserControl 重新创建它。这听起来像是一个简单的请求,但是如果 UserControl 不在循环中,我可能会要求不可能的事情。但希望子控件为 UserControl 重新创建它。这听起来像是一个简单的请求,但是如果 UserControl 不在循环中,我可能会要求不可能的事情。

4

4 回答 4

1

您没有具体提到您在页面生命周期的哪个点创建和添加这些控件。为了使回发工作,所有创建(和连接)和“重新创建”都必须在 page_load 事件之前完成。

在 page_init 执行此操作,如果 ID 相同,则视图状态机制应接管回发值。

我在这里遇到了另一种方法:http: //www.codeproject.com/KB/viewstate/retainingstate.aspx

于 2009-07-19T14:32:32.940 回答
0

好的,如果我错了,请纠正我,您的 Create() 方法实际上实例化并将您的内部控件设置为已知状态;我看到您已经有了对按钮的引用,那么为什么此时还需要一个额外的 Click 事件呢?

当您调用 Create() 时,您将初始化控件及其按钮,然后,当您知道按钮在那里时,连接您的事件处理程序并传递您在那里的参数。

MyControl : CompositeControl
{
    void Create(args, EventHandler click)
    {
        // init & set up your control

        // other processing

        MyButton.OnClick += click;
    }
}
于 2009-07-19T14:24:48.850 回答
0

您将控件动态插入占位符的动机是什么?请求之间并不真正存在页面,因此任何动态插入的控件都无法生存。你基本上不得不伪造它。

您可能要考虑的一个选项是编写具有不同呈现模式但具有一致事件接口的自定义控件。另一种是使用 ASP.NET MultiView 控件,它只会在 HTML 中呈现可见视图,但仍会在不可见视图中维护事件处理程序。

于 2009-07-18T17:19:29.957 回答
0

您应该始终将相同的 ID 用于动态创建的控件,如果您失败,有时不会引发控件事件,

希望这有帮助。

于 2010-05-27T18:10:53.797 回答