【问题标题】:Prevent CheckBox Checked event from firing防止 CheckBox Checked 事件触发
【发布时间】:2012-04-09 20:07:20
【问题描述】:

我有一些在代码上动态创建的复选框。我确实使用条形码阅读器读取条形码。当我使用条形码时,我试图阻止 Unchecked 和 Checked 事件触发。对于那个效果我:

  1. 仅当我将焦点放在复选框上时才分配这两个事件,当我失去焦点时我将事件取出。
  2. 在每个 Checked 和 Unchecked 事件之后,我将焦点分配给窗口中的另一个控件(因此会触发 LostFocus 事件)

但是我使用了条形码阅读器,所有的 CheckBoxes 对象在被选中时都会收到 Unchecked 事件(但如果它们未被选中则不会收到 Checked 事件)。

有没有办法防止这种情况发生?

使用 Unchecked 方法的唯一地方是代码显示中的地方,而不是应用程序代码中的其他地方。

指向更好的方法来处理复选框的这种动态创建不会不受欢迎。

private void SomeMethod ()
{
  foreach (KeyValuePair<String, String> kvp in someDictionary)
  {
    CheckBox checkBox = new CheckBox();
    checkBox.Content = kvp.Key;
    checkBox.GotFocus +=new RoutedEventHandler(checkBox_GotFocus);
    checkBox.LostFocus += new RoutedEventHandler(checkBox_LostFocus);
    checkBox.ClickMode = ClickMode.Release;
    Grid.SetRow(checkBox, fileSelectionGrid.RowDefinitions.Count);
    fileSelectionGrid.Children.Add(checkBox);
    RowDefinition row = new RowDefinition();
    fileSelectionGrid.RowDefinitions.Add(row);
  }
}

void checkBox_LostFocus(object sender, RoutedEventArgs e)
{
  CheckBox checkBox = sender as CheckBox;
  checkBox.Checked -= new RoutedEventHandler(checkBox_Checked);
  checkBox.Unchecked -= new RoutedEventHandler(checkBox_Unchecked);
}

void checkBox_GotFocus(object sender, RoutedEventArgs e)
{
  CheckBox checkBox = sender as CheckBox;
  checkBox.Checked += new RoutedEventHandler(checkBox_Checked);
  checkBox.Unchecked += new RoutedEventHandler(checkBox_Unchecked);
}

编辑:

刚刚检查了当 CheckBox 没有焦点时没有引发 click 事件。

【问题讨论】:

  • 我看不到未注册的事件如何被触发。条形码阅读器是否触发 checkBox_GotFocus 事件?
  • 不,没有。我也很困惑。
  • 当它触发时,发件人是什么?
  • 然后您的条形码“阅读器”似乎以某种方式将焦点放在复选框上并取消选中它们。
  • 似乎并非如此。读者只需通过消息中心发送消息。读者根本不知道复选框所在的屏幕确实存在。此外,当屏幕的消息处理程序注册时,复选框不存在。它们仅在收到特定消息后才创建,这不是我在发生奇怪行为时收到的消息。我确实检查过创建复选框的方法没有被调用两次(它不是)。

标签: c# wpf


【解决方案1】:

通常对于此类问题,我声明一个 bool 标志,该标志在事件将触发的代码行之前和之后分配值,当该事件被触发时,它首先要做的是检查该标志值。

例如

bool flag = false;

private void SomeMethod()
{
  flag = true;
  YourCheckBox.checked = false;
  flag = false;
}

void YourCheckBox_Checked(object sender, RoutedEventArgs e)
{
  if (flag)
     return;

  // Do something....
}

void YourCheckBox_UnChecked(object sender, RoutedEventArgs e)
{
  if (flag)
     return;

  // Do something....
}

当我指定 flag = true 时,下一行将触发选择更改事件。当我这样做时,它会返回因为标志设置为真;

【讨论】:

  • 就我而言,代码中的值没有改变。所以没有YourCheckBox.checked。它只能通过 GUI 完成。
  • 在您的示例中,您有事件 checkBox_Checked 和 checkBox_Unchecked。
  • 好吧,其实在他的示例中,应该是:YourCheckBox.IsChecked = false;
【解决方案2】:

不要基于失去焦点,尝试在读取条形码之前直接禁用事件处理程序,然后再启用它们。像这样的:

public void ReadBarcode(ComboBox cmbx)
{
    FieldInfo info = cmbx.GetType().GetField("SelectedIndexChanged", BindingFlags.Instance | BindingFlags.NonPublic);
    if (info != null)
    {
       object obj = info.GetValue(cmbx);
       if (obj is EventHandler)
       {
          EventHandler handler = (EventHandler)obj;
          cmbx.SelectedIndexChanged -= handler;
          //              
          // Perform your bar code reading here.
          // 
          cmbx.SelectedIndexChanged += handler;
       }
    }
}

为了清楚起见,我使用了单个组合框,显然您可以对一组组合框使用相同的技术

【讨论】:

  • 条形码读取发生在不同的 dll 中,并且消息通过消息传递系统传递。找到了解决方案/hack,一旦 Slashdot 允许我将发布。
【解决方案3】:

我找到了解决方案。我为接收焦点的控件添加了 KeyUp 和 KeyDown 的事件处理程序(条形码输入被认为是击键):

e.Handled = true;

这阻止了接收它们的复选框。

根据文档,这是一个冒泡事件。控件和复选框是堂兄弟

  • 控制->网格1->父网格
  • 复选框->网格 2->父网格

我没想到它会先上升到父网格,然后再下降。我需要阅读有关 WPF 的更多信息。

在我看来,这有点骇人听闻。如果有人得到更好的答案,我会标记它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-10
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-12
    相关资源
    最近更新 更多