4

我在一个窗口中有很多控件,包括复选框和组合框。我想跟踪 CheckBox.IsChecked 事件,所以我在 Windows 级别定义了一个事件处理程序为

<Grid CheckBox.Checked="OnModified" CheckBox.Unchecked="OnModified">

问题是 ComboBox 在鼠标单击一个项目后也会立即触发相同的事件。我认为我的事件处理程序应该只捕获 CheckBox 的 Checked 事件,而不是 ToggleButton 的。我错过了什么吗?

编辑:正如我在下面指出的那样,我认为它会以这种方式工作,因为我阅读了Matthew MacDonald 的书“ Pro WPF in C# 2010 ”。在第 164 页,他首先给出了这个示例代码:

<StackPanel Button.Click="DoSomething" Margin="5">   
  <Button Name="cmd1">Command 1</Button> 
  <Button Name="cmd2">Command 2</Button> 
  <Button Name="cmd3">Command 3</Button> 
  ... 
</StackPanel>  

然后,他特别指出:

注意 Click 事件实际上是在 ButtonBase 类中定义的,由 Button 类继承。如果将事件处理程序附加到 ButtonBase.Click,则当单击任何 ButtonBase 派生控件(包括 Button、RadioButton 和 CheckBox 类)时,将使用该事件处理程序。如果将事件处理程序附加到 Button.Click,它仅用于 Button 对象。

现在,我误解了他,还是他的笔记错了?

4

5 回答 5

2

实际上没有单独的CheckBox.Checked事件。如果您查看此页面:

并找到Checked事件,您将看到它是从ToggleButtonso继承的,ToggleButton.Checked并且CheckBox.Checked是同一事件的两个不同名称。

由于您订阅了“通配符”事件,因此在事件处理程序中,您可以检查发送者或来源以查看您是否感兴趣。

编辑:

为了解决您对书籍报价的后续问题,我认为报价至少具有误导性。这是一个反例,它显示了CheckBox对事件的反应,Button即使CheckBox不是从 派生的Button

<CheckBox Button.Click="CheckBox_Click"/>

当然没有Button.Click事件,只有ButtonBase.Click事件,但那是报价的症结所在。如果引用字面上是真的,则要么不允许使用此语法,要么不会触发事件,这两者都不正确。

于 2011-05-01T16:06:05.663 回答
1

这是因为您在网格上设置了事件,因此网格中包含的任何具有Checkbox.Checked路由事件的子项都会响应该事件。在您的情况下,碰巧ComboboxItem使用相同的路由事件(我相信其他控件也可能重用它)

处理此问题的最简单方法是向您的处理程序添加一个测试,如下所示:

private void OnModified(object sender, EventArgs args)
{
    if ( sender is CheckBox )
    {
        CheckBox ckBox = sender as CheckBox;
        // do stuff with ckBox
    }
}
于 2011-05-01T15:57:05.237 回答
1

发生这种情况是因为这两个事件都在元素树中冒泡,并且都到达了您的处理程序(CheckBox继承ToggleButton,因此实际上是相同的事件)。你无法阻止这一点。相反,您可以做的是检查事件是否由. 可以这样做:CheckBox.CheckedToggleButton.CheckedCheckBox

private void OnModified(object sender, RoutedEventArgs e)
{
    // Filter the event by its source
    if (e.Source.GetType() != typeof(CheckBox))
        return;

    // Your handling code         
}
于 2011-05-01T15:58:16.263 回答
0

我曾经通过检查它是否聚焦来防止 Checkbox.Checked 事件。因为当它从绑定中触发时,它不是聚焦的,但是当你点击它时,它就会聚焦。

 if(cbo.IsFocused){ // code here }

希望这可以帮助。布莱里姆。

于 2020-04-10T12:46:06.500 回答
-1

我是“C# 2010 中的 Pro WPF”的作者,我可以确认注释框中的文本属于“我抽什么烟?” 类别。根据您在标记中引用它的方式,Click 事件之间没有区别。

马修

于 2011-05-04T15:32:30.303 回答