【问题标题】:WinForms: temporarily disable an event handlerWinForms:暂时禁用事件处理程序
【发布时间】:2009-04-13 16:36:19
【问题描述】:

如何在 WinForms 中临时禁用事件处理程序?

【问题讨论】:

  • 你能在更高的层次上分享你正在做的事情吗?因为您可能不想禁用 ALL 事件处理程序(想到表单的默认绘制和移动处理程序)。
  • 我只是不想在以编程方式更新控件时捕获控件状态的变化。是的,我不想禁用 ALL 事件处理程序,只是“一个事件处理程序”。 stackoverflow.com/questions/744436/…

标签: c# winforms


【解决方案1】:

可能,最简单的方法(不需要取消订阅或其他东西)是声明一个布尔值并在处理程序的开头检查它:

bool dontRunHandler;

void Handler(object sender, EventArgs e) {
   if (dontRunHandler) return;

   // handler body...
}

【讨论】:

  • 这个很简单,但是如果你经常使用这个代码会很乱。
  • 这不是竞争条件吗?
  • @k1ngjulien 如果一切都在同一个线程上运行,则不会,因为它通常是使用 winforms。
【解决方案2】:

从什么角度禁用?如果你想从处理程序的委托列表中删除你范围内的方法,你可以这样做..

object.Event -= new EventHandlerType(your_Method);

这将从委托列表中删除该方法,您可以稍后重新附加它

object.Event += new EventHandlerType(your_Method);

【讨论】:

  • 我认为您的意思是 your_Method 而不是 your_Method()。从 C# 2.0 开始,您也不需要“new EventHandlerType”部分 - 只需 object.Event += yourMethod;和 object.Event -= yourMethod;
  • 是的,我的意思是它是无括号的;)。但是,不知道隐式委托构造;很高兴知道。
  • 这个想法适用于我(与接受的答案相比)在我需要为组合框 EditValueChanged 临时禁用处理程序的情况下。
  • 这应该是公认的答案。
【解决方案3】:

我正在这样做,使用控件扩展。

public static void SetDatasource(
  this ComboBox cb, 
  object dataSource, 
  EventHandler _SelectedIndexChanged_eventHandler = null, 
  EventHandler _SelectedValueChanged_eventHandler = null)
{
//disable events
  if (_SelectedIndexChanged_eventHandler != null) cb.SelectedIndexChanged -= _SelectedIndexChanged_eventHandler;
  if (_SelectedValueChanged_eventHandler != null) cb.SelectedValueChanged -= _SelectedValueChanged_eventHandler;
  if (cb.InvokeRequired)
  {
    cb.BeginInvoke(new _d_SetDatasource_ComboBox(SetDatasource), new object[] { cb, dataSource, _SelectedIndexChanged_eventHandler});
  }
  else
  {
    cb.DataSource = dataSource;
    //events enabled again
    if (_SelectedIndexChanged_eventHandler != null) cb.SelectedIndexChanged += _SelectedIndexChanged_eventHandler;
    if (_SelectedValueChanged_eventHandler != null) cb.SelectedValueChanged += _SelectedValueChanged_eventHandler;
  }
}
private delegate void _d_SetDatasource_ComboBox(ComboBox cb, object dataSource, EventHandler _SelectedIndexChanged_eventHandler = null, EventHandler _SelectedValueChanged_eventHandler = null);

【讨论】:

    【解决方案4】:

    禁用组件的事件。伪代码:

    YourComponent.YourComponentEvent -= ExistingMethodForTheEvent;
    

    启用

    YourComponent.YourComponentEvent += ExistingMethodForTheEvent;
    

    DataGridView 中的 CellFormatting 等事件示例:

    //enabling
    DataGridView1.CellFormatting += DataGridView1_CellFormatting;
    //disabling
    DataGridView1.CellFormatting -= DataGridView1_CellFormatting;
    
    private void DgvBillings_CellFormatting(...) {
    ...
    }
    

    【讨论】:

      【解决方案5】:

      如果您只为一堆复选框或单选按钮使用一个事件处理程序,您还可以使用类似的东西:

      var lSender = sender as RadioButton;
      if (lSender?.Checked != true)
          return;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多