Question

I have a TreeView and have created a basic TreeItem type. Each TreeItem has a header, a TreeItem Collection for children and a collection for a possible context menu. The TreeItem class has those objects:

public delegate void dExecute(TreeItem item);

public dExecute ExecuteTarget { get; set; }
public object Tag { get; set; }
public string Header { get; set; }
public List<TreeItem> Children { get; set; }
public List<TreeItem> ContextMenu { get; set; }

The context menu uses again a HierarchicalDataTemplate to display TreeItem objects (I use the TreeItem class for the items in the treeview AND in the context menu). The context menu looks like this:

<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" Visibility="{Binding ShowContextMenu}" ItemsSource="{Binding ContextMenu}">
    <ContextMenu.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}">
            <TextBlock Text="{Binding Header}"  />
            <HierarchicalDataTemplate.ItemContainerStyle>
                <Style TargetType="MenuItem">
                    <Setter Property="Command" Value="{Binding Execute}"/>
                </Style>
            </HierarchicalDataTemplate.ItemContainerStyle>
        </HierarchicalDataTemplate>
    </ContextMenu.ItemTemplate>
</ContextMenu>

The context menu is rendered as I want it to be. I have created a context menu that I just attach to some of my items in the tree view. This is its content.

public List<TreeItem> ContextMenu
{
    get
    {
        List<TreeItem> list = new List<TreeItem>();
        TreeItem ti = new TreeItem("Some Action") { ExecuteTarget = targetMethod};
        list.Add(ti);
        ti = new TreeItem("test");
        ti.Children.Add(new TreeItem("foo") { ExecuteTarget = targetMethod});
        ti.Children.Add(new TreeItem("bar") { ExecuteTarget = targetMethod});
        ti.Children.Add(new TreeItem("foo") { ExecuteTarget = targetMethod});
        TreeItem ti2 = new TreeItem("inner"){ ExecuteTarget = targetMethod};
        ti.Children.Add(ti2);
        ti2.Children.Add(new TreeItem("foo") { ExecuteTarget = targetMethod});
        list.Add(ti);
        return list;
    }
}

The context menu looks like this.

The rendered context menu

It looks as it should be. The commands work as they should. EXCEPT for the command on the highest level of the context menu. When I click on "Some Action" nothing happens. I assume that I have to add something to XAML, but I have no idea where.

Was it helpful?

Solution

<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" Visibility="{Binding ShowContextMenu}" ItemsSource="{Binding ContextMenu}">
    <ContextMenu.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}">
            <TextBlock Text="{Binding Header}"  />
            <HierarchicalDataTemplate.ItemContainerStyle>
                <Style TargetType="MenuItem">
                    <Setter Property="Command" Value="{Binding Execute}"/>
                </Style>
            </HierarchicalDataTemplate.ItemContainerStyle>
        </HierarchicalDataTemplate>
    </ContextMenu.ItemTemplate>

    <!-- this is what you're missing -->
    <ContextMenu.ItemContainerStyle>
        <Style TargetType="MenuItem">
            <Setter Property="Command" Value="{Binding Execute}"/>
        </Style>
    </ContextMenu.ItemContainerStyle>
</ContextMenu>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top