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

后端 未结 4 1872
情书的邮戳
情书的邮戳 2020-12-16 16:22

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

  

        
相关标签:
4条回答
  • 2020-12-16 16:50

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

    <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>
    
    0 讨论(0)
  • 2020-12-16 17:02

    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.

    0 讨论(0)
  • 2020-12-16 17:10
    <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

    0 讨论(0)
  • 2020-12-16 17:13

    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 DataContext cannot be found.

    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 DataContext you want.

    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:

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

    <DataTemplate DataType="{x:Type snapshot:InstrumentDetails}">
      <StackPanel Orientation="Vertical" Style="{StaticResource ContextMenuStyle}">                 
          <Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">
    
    0 讨论(0)
提交回复
热议问题