2013-04-26 85 views
1

我是WPF的新手,並且正在通過.net 4.5中專業WPF的示例。在命令章節中,有一個示例,其中多個控件可以發送相同的命令。我正在使用Button,CheckBox和MenuItem來觸發New命令。WPF:「ApplicationCommands.New」在MenuItem的情況下顯示不正確的源碼

我面臨的問題是,如果MenuItem第一次被按下,源顯示正確。但是,單擊按鈕或複選框後,單擊MenuItem會顯示最後一個控件Button或CheckBox的來源,無論按下哪個按鈕。我找不到我的代碼出了什麼問題,或者爲什麼WPF中的MenuItem顯示此行爲。

以下是代碼。

<Window x:Class="WpfApplication1.CommandSample" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="CommandSample" Height="300" Width="300"> 
    <Window.CommandBindings> 
    <CommandBinding Command="New" Executed="CommandBinding_Executed" /> 
    </Window.CommandBindings> 
    <StackPanel> 
    <Button Command="New" MaxWidth="80" MaxHeight="30" Content="{x:Static ApplicationCommands.New}" /> 
    <Menu MaxHeight="30" VerticalAlignment="Top"> 
     <MenuItem Header="File"> 
     <MenuItem Command="New"></MenuItem> 
     </MenuItem> 
    </Menu> 
    <CheckBox Command="New"></CheckBox> 

    </StackPanel> 
</Window> 

namespace WpfApplication1 { 
    public partial class CommandSample: Window { 
    public CommandSample() { 
     InitializeComponent(); 
    } 
    private void CommandBinding_Executed(object sender,ExecutedRoutedEventArgs e) 
    { 
     MessageBox.Show("New Command launched by " + e.Source); 
    } 
    } 
} 

回答

2

是的這是正確的(或至少這是它的設計)。路由命令根據您指定的CommandTarget啓動路由。如果通常沒有指定引發事件的對象,則以自身作爲起點(在這種情況下爲MenuItem)。因此,在這種情況下,路由從MenuItem開始,就像您所期望的那樣。沒有任何處理它的地方,所以CommandManager上升到父鏈。當它碰到一個FocusScope的元素時(例如Menu),它會檢查「父級」FocusScope的FocusedElement(例如,在本例中爲菜單的父級的FocusScope)。如果有一個FocusedElement(當你在窗口的焦點範圍內聚焦一個元素,比如你的按鈕,複選框,你可能放入該棧面板的文本框等等時,會有一個),然後CommandManager開始從事件路由那個元素。當它確實創建了一個新的ExecutedRoutedEventArgs,其中OriginalSource是起始元素(如按鈕,複選框,文本框),然後繼續向上路由樹。

因此,當您第一次運行應用程序時,窗口的FocusedElement(在您的示例中爲根焦點範圍)爲null,因此不需要重新路由,因此CommandManager只是繼續沿着Menu這就是爲什麼MenuItem顯示爲Source & OriginalSource。當你點擊按鈕時,你給了該鍵盤焦點,並且作爲它的一部分,它也成爲其焦點範圍(即包含它的FocusScope的FocusedElement)的邏輯焦點元素。因此,當MenuItem隨後被點擊並且CommandManager最終到達Menu時,它將重新路由到Button(或者你在窗口聚焦範圍內聚焦的任何東西),然後從那裏開始路由。我說這是預料之中的,因爲使用路由命令時,您希望路由通過邏輯聚焦的元素,例如,菜單項的剪切命令會觸發剪切窗口中具有焦點的文本框。

+0

太好了,非常感謝您的詳細解釋。這解釋了它。 – SajidQ 2013-04-26 17:02:04

+0

我想給+1,但我是新的,沒有15個代表,所以它不會允許我。但是一旦我達到這個標記,我肯定會:) – SajidQ 2013-04-26 17:13:03

相關問題