0

I have a ContextMenu that appears on a right click of a TreeViewItem. What I would like to do now is pass a couple of details about the TreeViewItem to the context menu.

How would I do that starting from here:

XAML

<TreeView x:Class="MyApp.TreeControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" 
         PreviewMouseLeftButtonDown="TreeView_PreviewMouseLeftButtonDown" 
         PreviewMouseMove="TreeView_PreviewMouseMove" 
         PreviewMouseRightButtonDown="TreeControl_OnPreviewMouseRightButtonDown">
<TreeView.ContextMenu>
    <ContextMenu>
        <MenuItem Name="dataItem1" Header="Property1"></MenuItem>
        <MenuItem Name="dataItem2" Header="Property2"></MenuItem>
        <Separator/>
        <MenuItem Name="taskItem" Header="Tasks" Click="TaskItem_OnClick"></MenuItem>
    </ContextMenu>
</TreeView.ContextMenu>
</TreeView>

I would like the words Property1 and Property2 replaced by the values of those properties in the TreeViewItem that was right clicked, sort of like : {binding selectedItem.Property1}

Code: (basically to highlight the clicked node)

private void TreeControl_OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    TreeViewItem treeViewItem = VisualUpwardSearch(e.OriginalSource as DependencyObject);

    if (treeViewItem != null)
    {
        treeViewItem.IsSelected = true;
        treeViewItem.Focus();
        e.Handled = true;
    }
}
Flat Eric
  • 7,971
  • 9
  • 36
  • 45
davecove
  • 1,001
  • 4
  • 16
  • 36

1 Answers1

0

The first thing that you need to do is to data bind your MenuItem.Header properties to an object that you set into the ContextMenu.DataContext:

<ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={
        RelativeSource Self}}">
    <MenuItem Name="dataItem1" Header="{Binding Property1}"></MenuItem>
    <MenuItem Name="dataItem2" Header="{Binding Property2}"></MenuItem>
    <Separator/>
    <MenuItem Name="taskItem" Header="Tasks" Click="TaskItem_OnClick"></MenuItem>
</ContextMenu>

What is this PlacementTarget.Tag, I hear you ask. Looking at the ContextMenu.PlacementTarget property page on MSDN, we see that it:

Gets or sets the UIElement relative to which the ContextMenu is positioned when it opens.

In plain English, that just means the UI element that has the ContextMenu applied to it. Now the Tag property is just a free property of type object that we can put anything into. In your case, we're going to put the ContextMenu.DataContext value in there because we can't set it directly, because the ContextMenu is not part of the general UI visual tree:

Now you didn't show the code where you apply the ContextMenu to the TreeViewItem, but in that same place, you need to set the Tag property to the object that you want to set as the ContextMenu.DataContext value. So we pass it in here and take it out in the ContextMenu as shown in the code example.

For more information, please take a look at my answers from the ContextMenu.PlacementTarget is not getting set, no idea why and Add context menu in datagrid, how to get the select Item value questions here on Stack Overflow.

Community
  • 1
  • 1
Sheridan
  • 68,826
  • 24
  • 143
  • 183