使用子项中的上下文菜单在 WPF 中添加 TreeView

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17431917/
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 09:08:04  来源:igfitidea点击:

Adding TreeView in WPF with context menu in subitems

c#wpfwpf-controls

提问by WAQ

In my WPF application, I want to add a TreeView control. The tree view control needs to be populated with items from database. So I bind the ItemsSource property to string collection.

在我的 WPF 应用程序中,我想添加一个 TreeView 控件。树视图控件需要用数据库中的项目填充。所以我将 ItemsSource 属性绑定到字符串集合。

Every item in the tree control can have from 0 to 32 child items. Again these items need to be binded. Each of these sub items should have a context menu with two options "Rename" and "Delete". How can I do this in WPF?

树控件中的每个项目都可以有 0 到 32 个子项目。同样,这些项目需要绑定。这些子项中的每一个都应该有一个上下文菜单,其中包含两个选项“重命名”和“删除”。我怎样才能在 WPF 中做到这一点?

回答by Michael Gunter

There are a few ways to do this. Here's one way that applies the context menu using a trigger that is bound to a property IsLeafon the underlying view model.

有几种方法可以做到这一点。这是使用绑定到IsLeaf基础视图模型上的属性的触发器来应用上下文菜单的一种方法。

MainWindow.xaml:

主窗口.xaml:

<Window x:Class="WpfScratch.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Window.Resources>

        <!-- the context menu for all tree view items -->
        <ContextMenu x:Key="TreeViewItemContextMenu">
            <MenuItem Header="Rename" />
            <MenuItem Header="Delete" />
        </ContextMenu>

        <!-- the data template for all tree view items -->
        <HierarchicalDataTemplate x:Key="TreeViewItemTemplate" ItemsSource="{Binding Nodes}">
            <TextBlock x:Name="TextBlock" Text="{Binding Text}" />
            <HierarchicalDataTemplate.Triggers>
                <DataTrigger Binding="{Binding IsLeaf}" Value="True">
                    <Setter TargetName="TextBlock" Property="ContextMenu" Value="{StaticResource TreeViewItemContextMenu}" />
                </DataTrigger>
            </HierarchicalDataTemplate.Triggers>
        </HierarchicalDataTemplate>

    </Window.Resources>

    <!-- the treeview -->
    <TreeView DataContext="{Binding TreeView}"
              ItemsSource="{Binding Nodes}"
              ItemTemplate="{StaticResource TreeViewItemTemplate}">
    </TreeView>

</Window>

MainWindow.xaml.cs:

主窗口.xaml.cs:

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new MainWindowModel(
            new MainWindowTreeViewModel(
                new MainWindowTreeViewNodeModel(
                    "1",
                    new MainWindowTreeViewNodeModel("A"),
                    new MainWindowTreeViewNodeModel("B"),
                    new MainWindowTreeViewNodeModel("C")),
                new MainWindowTreeViewNodeModel(
                    "2",
                    new MainWindowTreeViewNodeModel("A"),
                    new MainWindowTreeViewNodeModel("B"),
                    new MainWindowTreeViewNodeModel("C")),
                new MainWindowTreeViewNodeModel(
                    "3",
                    new MainWindowTreeViewNodeModel("A"),
                    new MainWindowTreeViewNodeModel("B"),
                    new MainWindowTreeViewNodeModel("C"))));
    }
}

MainWindowModel.cs:

主窗口模型.cs:

public class MainWindowModel
{
    public MainWindowModel(MainWindowTreeViewModel treeView)
    {
        TreeView = treeView;
    }

    public MainWindowTreeViewModel TreeView { get; private set; }
}

public class MainWindowTreeViewModel
{
    public MainWindowTreeViewModel(params MainWindowTreeViewNodeModel[] nodes)
    {
        Nodes = nodes.ToList().AsReadOnly();
    }

    public ReadOnlyCollection<MainWindowTreeViewNodeModel> Nodes { get; private set; }
}

public class MainWindowTreeViewNodeModel
{
    public MainWindowTreeViewNodeModel(string text, params MainWindowTreeViewNodeModel[] nodes)
    {
        Text = text;
        Nodes = nodes.ToList().AsReadOnly();
    }

    public string Text { get; private set; }
    public ReadOnlyCollection<MainWindowTreeViewNodeModel> Nodes { get; private set; }
    public bool IsLeaf { get { return Nodes.Count == 0; } }
}