2016-12-06 73 views
0

我在WPF中有一個databound層次菜單。所有項目都顯示出來,但命令僅針對菜單的葉子,而不是具有子項目的項目。我猜想通過展開子菜單來覆蓋命令... 即使對於帶有子項的菜單項,我如何獲得執行命令?WPF - 我如何給兒童的菜單項命令

我現在有什麼是

<UserControl ...> 
    <WrapPanel> 
     <Menu> 
      <Menu.Resources> 
       <Style x:Key="MenuItemStyle" TargetType="MenuItem" d:DataContext="{d:DesignInstance local:TreeItem}"> 
        <Setter Property="Command" Value="{Binding DataContext.AddColumnCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"/> 
        <Setter Property="CommandParameter" Value="{Binding}"/> 
       </Style> 
      </Menu.Resources> 
      <MenuItem Header="Add ▼" ItemsSource="{Binding AvailableFields}"> 
       <MenuItem.ItemTemplate> 
        <HierarchicalDataTemplate DataType="{x:Type local:TreeItem}" ItemsSource="{Binding NestedItems}" ItemContainerStyle="{StaticResource MenuItemStyle}"> 
         <ContentPresenter Content="{Binding Annotation}"/> 
        </HierarchicalDataTemplate> 
       </MenuItem.ItemTemplate> 
      </MenuItem> 
     </Menu> 
    </WrapPanel> 
</UserControl> 

我發現了一個question with a similar name,但情況是不同的,它並沒有一個很好的答案呢。

回答

0

顯示所有項目,但命令只針對菜單的葉子,而不是具有子項目的項目。

是的,這是預期的行爲,因爲點擊具有子項目的MenuItem應該展開子項目的子菜單。它不執行命令。

如果要展開的子項,然後執行,你可以處理菜單項的的PreviewMouseLeftButtonDown事件的命令:

<Style TargetType="{x:Type MenuItem}"> 
    <Setter Property="Command" Value="{Binding DataContext.AddColumnCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"/> 
    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="OnMouseDown" /> 
</Style> 

-

private void OnMouseDown(object sender, MouseButtonEventArgs e) 
{ 
    MenuItem mi = sender as MenuItem; 
    if (mi != null && mi.Command != null && mi.HasItems) 
     mi.Command.Execute(mi.CommandParameter); 
} 

注意處理的代碼 - 事件視圖後面並沒有真正打破MVVM模式,因爲您只是從代碼隱藏中調用視圖模型的命令,而不是從相同視圖的XAML標記中調用視圖模型。但是如果你不喜歡這種方法,你可以使用附加的行爲:https://www.codeproject.com/articles/28959/introduction-to-attached-behaviors-in-wpf