0

The following code produces a TreeView as seen below. When you right click any of the child nodes (not parents), I would like a simple context menu to display.

enter image description here

Here is the code I am using to create the tree view. I need to use the HierarchicalDataTemplate so the solution must include that.

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; }
    }
}

SAMPLE CONTEXT MENU

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

Thanks for the help!


UPDATE

Here is the updated XAML that makes the content menu work for the child node types only (thanks to @EdPlunket for the answer)

<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 Answer 1

1

This should do it.

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

    <!-- resources etc. -->

If you want different context menus for the different types of items, put them on the TextBlocks in the templates.

Sign up to request clarification or add additional context in comments.

2 Comments

I have a similar issue I need different context menu depending on the data type. I cannot set them on the data template, TextBlock in your case, because I have a custom control template that highlights an entire row and I need it to show the context menu if the user right clicks anywhere on that row.
@KennethParker No idea. Ask the mods.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.