【问题标题】:Block other events on Page_Load()阻止 Page_Load() 上的其他事件
【发布时间】:2014-11-27 01:11:00
【问题描述】:

我有一个类似下面的案例。

protected void Page_Load(object sender, EventArgs e)
{
    if (SomeCheck())
    { 
        // Block all other events from happening
    }
}
protected void Button1_Click(object sender, EventArgs e)
{

}
protected void Button2_Click(object sender, EventArgs e)
{

}
protected void Button3_Click(object sender, EventArgs e)
{

}
//..
//..
// Other Event Handlers
//..
//..

我有多个事件处理程序,例如此处的按钮单击(在上面的示例中),并且有一个 Page_Load 我想在其中检查某些内容,并根据该检查我想阻止其他事件正在发生。 我怎样才能做到这一点?我在这里使用了正确的事件还是应该对Pre_render 或其他东西进行检查?

更新

我实际上想要一个解决方案,在这种解决方案中,我不必执行任何额外的代码,也不必担心每次添加新的事件处理程序时检查每个事件处理程序上的 bool 变量很快就会在代码维护中变得困难。

【问题讨论】:

  • 为什么不设置一个 bool shouldDoEvent 并在每个事件处理程序中检查它?
  • 我想要一个做就忘记的解决方案,不想担心在我拥有或将来添加的每个事件处理程序中实现该检查。
  • @J.Steen 怎么样? asp.net 是无状态的!
  • 您可以删除按钮Button1.onClick -= new EventHandler(Button1_Click);的每个事件处理程序

标签: c# asp.net .net


【解决方案1】:

尝试使用此函数从作为输入传递的通用按钮中删除点击处理程序

private void RemoveClickEvent(Button b)
{
   FieldInfo f1 = typeof(Control).GetField("EventClick", 
   BindingFlags.Static | BindingFlags.NonPublic);
   object obj = f1.GetValue(b);
   PropertyInfo pi = b.GetType().GetProperty("Events",  
   BindingFlags.NonPublic | BindingFlags.Instance);
   EventHandlerList list = (EventHandlerList)pi.GetValue(b, null);
   list.RemoveHandler(obj, list[obj]);
}

此代码来自MSDN

更新

在谷歌搜索不同的问题后,我尝试为您的问题制作一个谜题:

逻辑是:从页面获取所有控件并获取其事件,每个事件销毁它

foreach (var control in this.Page.Form.Controls)
    {
        foreach(var event in control.GetType.GetEvents()){
            ClearEventInvocations(control, evt.Name);
        }
    }

功能

public static void ClearEventInvocations(this object obj, string eventName)
    {
        var fi = obj.GetType().GetEventField(eventName);
        if (fi == null) return;
        fi.SetValue(obj, null);
    }

    private static FieldInfo GetEventField(this Type type, string eventName)
    {
        FieldInfo field = null;
        while (type != null)
        {
            /* Find events defined as field */
            field = type.GetField(eventName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);
            if (field != null && (field.FieldType == typeof(MulticastDelegate) || field.FieldType.IsSubclassOf(typeof(MulticastDelegate))))
                break;

            /* Find events defined as property { add; remove; } */
            field = type.GetField("EVENT_" + eventName.ToUpper(), BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);
            if (field != null)
                break;
            type = type.BaseType;
        }
        return field;
    }

代码未经测试,如有错误请见谅。我想尝试为您提供解决问题的正确方法。缺少的一件事可能是对控件父母的父母的递归调用

感谢this其他回答

【讨论】:

  • 那是一段不错的代码,但在实际情况下,我的屏幕上不会只有按钮,可能会有网格、下拉菜单、复选框等。此外,可能还有很多事件,比如DataBinding、ItemCommand 等。
【解决方案2】:

假设这些都是用户创建的事件:DropDownLists、Buttons 等。 你应该改变连接事件的方式,只添加你需要的。

删除所有事件,例如OnClick="clickEventName" 从您的 .aspx 页面中移到后面的代码中。

protected void Page_Load(object sender, EventArgs e)
{
    Button1.Click += Button1_Click;

    if (!SomeCheck())
    { 
        // Only fire Button2 Click if SomeCheck Fails
        Button2.Click += Button2_Click;

    }
}
protected void Button1_Click(object sender, EventArgs e)
{

}
protected void Button2_Click(object sender, EventArgs e)
{

}

我个人认为这是连接控制事件而不是使用页面的更好方法。

【讨论】:

    猜你喜欢
    • 2015-06-23
    • 2018-10-11
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-06
    相关资源
    最近更新 更多