2011-05-01 99 views
4

我在窗口中有很多控件,包括複選框和組合框。我想跟蹤CheckBox.IsChecked事件,所以我定義在Windows級別的事件處理程序WPF:如何防止CheckBox.Checked事件被ComboBox作爲ToggleButton觸發?

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

的問題是,同樣的事件是由組合框後,鼠標右鍵單擊某個項目也被解僱。我認爲我的事件處理程序應該只捕獲CheckBox的Checked事件,而不是ToggleButton的事件。我錯過了什麼嗎?

編輯: 正如我在下面所指出的,我認爲它會以這種方式工作,因爲我讀馬修·麥克唐納的書「臨WPF在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類中定義 和 通過按鈕繼承類。如果您 附加一個事件處理程序 ButtonBase.Click,被點擊時任 ButtonBase衍生控制 (包括按鈕,單選按鈕, 和CheckBox類),該事件處理 將被使用。如果將一個事件處理函數 附加到Button.Click,則該函數僅用於Button對象。

現在,我誤解了他,還是他的說明有誤?

+0

你的事件處理程序是如何「附加」的?一些代碼會很好! – 2011-05-01 15:40:56

+0

好的,我編輯了這個問題來包含一些代碼。 – newman 2011-05-01 15:54:48

回答

2

實際上並沒有單獨的CheckBox.Checked事件。如果你看看這個頁面:

,並找到Checked事件中,你將看到它是從ToggleButton所以ToggleButton.CheckedCheckBox.Checked繼承是同一事件的兩個不同的名字。

由於您訂閱了「通配符」事件,在事件處理程序,你可以查看發件人或源代碼,看看你那是一個你感興趣的

編輯:

要解決您關於書籍報價的後續問題,我認爲報價至少是誤導性的。這裏是一個反例,顯示即使CheckBox不是從Button衍生的CheckBox反應Button事件:

<CheckBox Button.Click="CheckBox_Click"/> 

當然沒有Button.Click事件,只是一個ButtonBase.Click事件,但畢竟是癥結所在引用。如果引用是真實的,那麼這個語法不會被允許或事件不會觸發,這兩個都不是真的。

+1

我以爲我已經讀過某處(在書中?)CheckBox.Checked和ToggleButton.Checked事件之間存在區別,即使前者是從後者。顯然,這是我的誤解。但是,如果我們確實有這種區別,我認爲它會更有用。無論如何,我接受了你的答案。 – newman 2011-05-01 16:42:09

+0

嘿,我剛剛在C#2010中找到了我誤解的來源:MacDonald's Pro WPF的第164頁,他寫道:「注意Click事件實際上是在ButtonBase類中定義的,並且由Button類繼承。如果附加了一個事件 處理ButtonBase.Click時,當任何ButtonBase派生的控件被點擊時(包括Button,RadioButton和CheckBox類),將使用該事件處理函數。如果您將事件處理函數附加到Button.Click,它僅用於Button對象「。這樣對嗎? – newman 2011-05-01 16:53:29

+0

由於我描述的原因,即使'CheckBox'不是來自'Button'並且處理程序仍然會被調用,您可以編寫''。所以我會說這本書至少是誤導性的。 – 2011-05-01 17:39:26

1

它是因爲你在網格上設置事件,因此網格中包含的具有Checkbox.Checked路由事件的任何子節點都將響應該事件。在你的情況下,它發生在ComboboxItem使用相同的路由事件(我相信其他控件可能會重用它)

最簡單的方法來處理這將是添加一個測試到你的處理程序,像這樣:

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

謝謝你的回答,但我只能接受一個。 – newman 2011-05-01 16:44:36

1

這是因爲這兩個事件被冒泡的元素樹,均達到您的處理程序(CheckBox繼承ToggleButton,因此CheckBox.CheckedToggleButton.Checked其實都是同一事件)。你無法防止這一點。你可以做的是檢查事件是否由CheckBox引發。它可以這樣做:

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

    // Your handling code   
} 
+0

感謝您的回答,但我只能接受一個... – newman 2011-05-01 16:44:11

-1

我是「C#2010中的臨WPF」的作者,我可以確認來自Note框的文本屬於「我吸菸是什麼?」。類別。根據您在標記中引用它的方式,Click事件之間沒有區別。

Matthew

相關問題