使用HierarchicalDataTemplates为TreeView创建WPF上下文菜单

时间:2018-04-26 17:20:51

标签: wpf xaml

以下代码生成TreeView,如下所示。当您右键单击任何子节点(而不是父节点)时,我希望显示一个简单的上下文菜单。

enter image description here

以下是我用来创建树视图的代码。我需要使用HierarchicalDataTemplate,因此解决方案必须包括。

XAML

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d">
    <Grid>
        <TreeView ItemsSource="{Binding Parents}">
            <TreeView.Resources>
                <HierarchicalDataTemplate DataType="{x:Type local:Parent}" 
                                          ItemsSource="{Binding Children}">
                        <TextBlock Text="{Binding Name}" />
                </HierarchicalDataTemplate>
                <HierarchicalDataTemplate DataType="{x:Type local:Child}">
                    <TextBlock Text="{Binding Name}" />
                </HierarchicalDataTemplate>
            </TreeView.Resources>
        </TreeView>
    </Grid>
</Window>

CODE

using System.Collections.Generic;
using System.Windows;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DataContext = new ViewModel();
        }
    }

    public class ViewModel
    {
        public ViewModel()
        {
            Parents = new List<Parent>();

            Parents.Add(new Parent()
            {
                Name = "Parent A",
                Children = new List<Child>() {
                        new Child() { Name = "Child A" },
                        new Child() { Name = "Child B" }
                    }
            });

            Parents.Add(new Parent()
            {
                Name = "Parent B",
                Children = new List<Child>() {
                        new Child() { Name = "Child C" },
                        new Child() { Name = "Child D" }
                    }
            });
        }

        public List<Parent> Parents { get; set; }
    }

    public class Parent
    {
        public Parent() { Children = new List<Child>(); }

        public string Name { get; set; }
        public List<Child> Children { get; set; }
    }

    public class Child
    {
        public string Name { get; set; }
    }
}

示例上下文菜单

<ContextMenu x:Key ="ArchiveFaxNodePopupMenu">
    <MenuItem Header="Delete" />
</ContextMenu>

感谢您的帮助!

更新

以下是更新的XAML,它使内容菜单仅适用于子节点类型(感谢@EdPlunket的答案)

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d">
    <Grid>
        <TreeView ItemsSource="{Binding Parents}">
            <TreeView.Resources>
                <HierarchicalDataTemplate DataType="{x:Type local:Parent}" 
                                          ItemsSource="{Binding Children}">
                        <TextBlock Text="{Binding Name}" />
                </HierarchicalDataTemplate>
                <HierarchicalDataTemplate DataType="{x:Type local:Child}">
                    <TextBlock Text="{Binding Name}">
                        <TextBlock.Resources>
                            <ContextMenu x:Key ="ArchiveFaxNodePopupMenu">
                                <MenuItem Header="Delete" />
                            </ContextMenu>
                        </TextBlock.Resources>
                        <TextBlock.Style>
                            <Style TargetType="TextBlock">
                                <Setter Property="ContextMenu" Value="{StaticResource ArchiveFaxNodePopupMenu}" />
                            </Style>
                        </TextBlock.Style>
                    </TextBlock>
                </HierarchicalDataTemplate>
            </TreeView.Resources>
        </TreeView>
    </Grid>
</Window>

1 个答案:

答案 0 :(得分:1)

这应该这样做。

<TreeView ItemsSource="{Binding Parents}">
    <TreeView.ItemContainerStyle>
        <Style TargetType="TreeViewItem">
            <Setter Property="ContextMenu" Value="{StaticResource ArchiveFaxNodePopupMenu}" />
        </Style>
    </TreeView.ItemContainerStyle>

    <!-- resources etc. -->

如果您需要不同类型的项目的不同上下文菜单,请将它们放在模板中的TextBlocks上。