如何在 wpf 中的层次结构数据模板中显示树视图项的上下文菜单

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13420994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 06:14:58  来源:igfitidea点击:

How to display context menu for treeview item in a hierarchial data template in wpf

c#wpftreeviewcontextmenu

提问by TrustyCoder

How to display context menu for tree view item in wpf using the hierarchical data template? How to display context menu only for CountryTemplate:

如何使用分层数据模板在 wpf 中显示树视图项的上下文菜单?如何仅显示 CountryTemplate 的上下文菜单:

  <HierarchicalDataTemplate  x:Key="DispTemplate">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Path=Label}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}" Tag="{Binding Path=Tag}">
            </TextBlock>
        </StackPanel>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate  x:Key="BuildingTemplate"  ItemsSource="{Binding Path=Building}" ItemTemplate="{StaticResource BuildingTemplate}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Path=Label}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}"/>
        </StackPanel>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate  x:Key="CityTemplate"  ItemsSource="{Binding Path=City}" ItemTemplate="{StaticResource CityTemplate}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Path=Label}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}"/>
        </StackPanel>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate x:Key="CountryTemplate" ItemsSource="{Binding Path=Country}" ItemTemplate="{StaticResource CountryTemplate}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Path=RootName}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}"/>
        </StackPanel>
    </HierarchicalDataTemplate>

回答by Raúl Ota?o

You also can add the ContextMenuto any visual child in the data template, for instance:

您还可以将 添加ContextMenu到数据模板中的任何可视子项,例如:

<HierarchicalDataTemplate x:Key="CountryTemplate" ItemsSource="{Binding Path=Country}" ItemTemplate="{StaticResource CountryTemplate}">
    <StackPanel Orientation="Horizontal">
        <StackPanel.ContextMenu>
            <ContextMenu>
                 <MenuItem Header="Header" Command="{Binding Command}"/> <!--This command should be in the data context (each country item)-->
            </ContextMenu>
        </StackPanel.ContextMenu>
        <TextBlock Text="{Binding Path=RootName}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}"/>
    </StackPanel>
</HierarchicalDataTemplate>

回答by Contango

One of the reasons why context menus do not work as cleanly as they could is because by default, they are in a different visual tree to everything else, so the DataContextcannot be found.

上下文菜单不能尽可能干净地工作的原因之一是因为默认情况下,它们与其他所有内容位于不同的可视化树中,因此DataContext无法找到。

The key insight is to create a <Style>that defines a context menu, then attach that style to a target element, which hooks up the context menu. This shifts the context menu into a visual tree that is lined up with the default DataContextyou want.

关键的见解是创建一个<Style>定义上下文菜单的 ,然后将该样式附加到目标元素,该元素连接上下文菜单。这会将上下文菜单转换为与DataContext您想要的默认值对齐的可视化树。

First, create the style:

首先,创建样式:

<UserControl.Resources>                                                                                                                        
    <ResourceDictionary>

        <!-- For the context menu to work, we must shift it into a style, which means that the context menu is now in a
        visual tree that is more closely related to the current data context. All we have to do then is set the style, 
        which hooks up the context menu. -->
        <Style x:Key="ContextMenuStyle" TargetType="{x:Type StackPanel}">
            <Setter Property="ContextMenu" Value="{DynamicResource TreeViewContextMenu}"/>
        </Style>
        <ContextMenu x:Key="TreeViewContextMenu">
            <MenuItem Header="Test" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.CmdDisplayDetailsGraph}"/>
        </ContextMenu>

Then, hook the context menu up anywhere you want, without running into issues caused by different visual trees.

然后,将上下文菜单连接到您想要的任何位置,而不会遇到由不同视觉树引起的问题。

Example 1:

示例 1:

<HierarchicalDataTemplate DataType="{x:Type snapshot:Details}" ItemsSource="{Binding DetailsList}">
    <StackPanel Orientation="Vertical" Style="{StaticResource ContextMenuStyle}">
        <ContentPresenter Content="{Binding}" ContentTemplate="{Binding View.DefaultDataRowTemplate}" />
</StackPanel>

Example 2:

示例 2:

<DataTemplate DataType="{x:Type snapshot:InstrumentDetails}">
  <StackPanel Orientation="Vertical" Style="{StaticResource ContextMenuStyle}">                 
      <Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">

回答by Hyman

<HierarchicalDataTemplate x:Key="CountryTemplate" ItemsSource="{Binding Path=Country}" ItemContainerStyle="{StaticResource CountryTemplateItemContainerStyle}" ItemTemplate="{StaticResource CountryTemplate}">
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding Path=RootName}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}" />
                        </StackPanel>
</HierarchicalDataTemplate>


<Style x:Key="CountryTemplateItemContainerStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="ContextMenu" Value="{DynamicResource TreeViewContextMenu}"/>
</Style>
 <ContextMenu x:Key="TreeViewContextMenu">
        <MenuItem .../>
 </ContextMenu>

As you can see, you can add your contextmenu in the Itemcontainerstyle of the HierarchicalDataTemplate

如您所见,您可以在 HierarchicalDataTemplate 的 Itemcontainerstyle 中添加您的上下文菜单

回答by TrustyCoder

Basically I came up with this

基本上我想出了这个

<HierarchicalDataTemplate  x:Key="ChildTemplate">
            <StackPanel Orientation="Horizontal">
                <StackPanel.ContextMenu>
                    <ContextMenu>
                        <MenuItem Header="Copy" CommandParameter="{Binding CopyTag}">
                        </MenuItem>
                        <MenuItem Header="Paste" CommandParameter="{Binding PasteTag}">
                        </MenuItem>
                        <ContextMenu.ItemContainerStyle>
                            <Style TargetType="MenuItem">
                                <Setter Property="Command" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.CopyPaste}"/>
                            </Style>
                        </ContextMenu.ItemContainerStyle>
                    </ContextMenu>
                </StackPanel.ContextMenu>
                <Image Source="/Images/Child.png" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Center" Style="{StaticResource TreeIconStyle}"/>
                <TextBlock Text="{Binding Path=Label}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}" Tag="{Binding Path=Tag}">
                </TextBlock>
            </StackPanel>
        </HierarchicalDataTemplate>

And have separate parameters for copy and paste to differentiate copy and paste in a single command.

并有单独的复制和粘贴参数,以区分单个命令中的复制和粘贴。