0

我正在使用自定义事件构建服务器控件,并且作为示例使用了这个MSDN 参考。但是回发时永远不会触发事件 - clickEventDelegate 始终为空:

      if (clickEventDelegate != null)
      {
            clickEventDelegate(this, e);
      }

这是我添加委托的方式:

     if (!Page.IsPostBack)
     {
          .....
         MYCONTROL.LeftClick+= FUNCTION;
     }

有任何想法吗?

4

2 回答 2

1

您没有发布足够多的代码来找出您的事件为空的原因。但我要列出标准模式。

这是您为自定义事件定义参数类的方式:

public class MyEventArgs : EventArgs
{
    private string MyField { get; private set; }

    public MyEventArgs(string myField)
    {
        MyField = myField;
    }
}

这是您定义自定义事件的方式:

public event EventHandler<MyEventArgs> MyEvent;

这是您在与事件相同的类中编写事件引发器的方式:

protected virtual void OnMyEvent(MyEventArgs e)
{
    EventHandler<MyEventArgs> myEvent = MyEvent; // for thread safety
    if (myEvent != null)
    {
        myEvent(this, e);
    }
}

这是您在定义事件的类(或派生类)中引发事件的方式:

OnMyEvent(new MyEventArgs("Test"));

这是您对派生类中的事件做出反应的方式:

protected override void OnMyEvent(MyEventArgs e)
{
    // TODO: Here you react to your event.
    base.OnMyEvent(e);
}

这是您在外国课程中注册活动的方式:

otherClass.MyEvent += delegate(object sender, EventArgs e)
{
    // TODO: Here you react to your event.
};
于 2013-05-24T00:08:51.627 回答
1

另一个答案只是解释了事件的工作原理,但完全忽略了问题的要点:Delegate is null during a postback

答案很简单。即使在回发期间,也只需每次订阅您的活动,因此您只需删除您的条件if (!Page.IsPostBack)

MYCONTROL.LeftClick+= FUNCTION;

我知道这是一个非常古老的问题,你不可能还在寻找答案。但是当我阅读

您没有发布足够多的代码来找出您的事件为空的原因

从上一个答案中,我不能让这种错误的说法像这样。

编辑:

为了添加更多解释,每次服务器返回要在浏览器中呈现的最终页面时,它都会丢失此特定连接的状态。想象一下,如果服务器应该将所有连接及其关联状态保存在内存中,那么您每天可能有数千个用户,以及何时“清理”这些内存?

所以不,那是不可行的,这就是他们创建的原因,ViewState这样浏览器就可以将以前的信息发送到服务器。但是,此 ViewState 可以保存某些变量或对象的值,但不保存事件与其委托之间的绑定。

回到具体的例子。如果你这样做

<asp:Button runat="server" ID="ButtonTest" OnClick="buttonTest_Click" Text="test" />

在您到达页面的Page_Load. 您可以在此处阅读有关 ASP.NET 生命周期的信息

如果您像这样分配事件处理程序

<asp:Button runat="server" ID="ButtonTest" Text="test" />

在您页面的服务器端:

protected void Page_Load(object sender, EventArgs e)
{
    ButtonTest.Click += ButtonTest_Click;
}

它的工作原理相同,只是订阅时间稍晚一些。

但是如果你把它装饰成一个条件

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        ButtonTest.Click += ButtonTest_Click;
    }
}

这将不起作用,因为尚未分配事件处理程序。请记住,您的服务器忘记了此特定连接的状态,并且必须在每个 HTTP POST 请求(PostBack)中初始化所有内容。

这与您问题的示例代码完全相同,因此您可以看到事件在本机 ASP.NET 控件或您声明的自定义控件上的工作方式相同。

于 2017-03-15T03:25:39.580 回答