WPF: How to prevent CheckBox.Checked event from triggering for ComboBox like ToggleButton?

I have many controls in the window, including checkboxes and dropdowns. I want to track the CheckBox.IsChecked event, so I defined a windows-level event handler as

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

The problem is that the same event is also triggered by the ComboBox immediately after clicking on the element. I thought that my event handler should log the CheckBox Checked event, not ToggleButton. Did I miss something?

EDIT: As I said below, I thought it would work like that because I read Matthew MacDonald's Pro WPF book in C # 2010. " On page 164, he first gave this sample code:

 <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> 

Then he specifically noted:

Note. The Click event is actually defined in the ButtonBase class and inherited by the Button class. if you bind an event handler to ButtonBase.Click, this event handler will be used when Clicking a ButtonBase (including Button, RadioButton, and CheckBox). If you attach a Button.Click event handler, it is used only for Button objects.

Now I misunderstood it or is it spelled incorrectly?

+4
source share
4 answers

Actually there is no separate CheckBox.Checked event. If you look at this page:

and find the Checked event, you will see that it inherits from ToggleButton , so ToggleButton.Checked and CheckBox.Checked are two different names for the same event.

Since you are subscribing to the โ€œwildcardโ€ event, in the event handler you can check the sender or source to see you, this is the one that interests you.

Edit:

To solve my next question regarding a quote from a book, I think the quote is at least misleading. Here is a counterexample that shows that the CheckBox responding to the Button event, although the CheckBox not derived from Button :

 <CheckBox Button.Click="CheckBox_Click"/> 

Of course, there is no Button.Click event, only the ButtonBase.Click event, but this is the essence of the quote. If the quote was literally true, or this syntax would not be resolved, or the event would not fire, none of them would be true.

+2
source

due to the fact that you are setting the event in the grid, so any children contained in the grid that have the Checkbox.Checked routed event will respond to the event. In your case, it happens that ComboboxItem uses the same routed event (and I'm sure other controls are probably using it again)

The easiest way to handle this is to add a test to your handler, for example:

 private void OnModified(object sender, EventArgs args) { if ( sender is CheckBox ) { CheckBox ckBox = sender as CheckBox; // do stuff with ckBox } } 
+1
source

This is because both events receive bubbles in the element tree and both reach your handler ( CheckBox inherits ToggleButton , so CheckBox.Checked and ToggleButton.Checked are actually the same events). You cannot prevent this. Instead, you can check if the event was raised by CheckBox . This can be done as follows:

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

I am the author of "Pro WPF in C # 2010", and I can confirm that the text from the "Note" field falls under "What did I smoke?". category. There is no difference between a Click event based on how you reference it in your markup.

Matthew

-1
source

All Articles