1

I'm trying to create a dynamic Context Menu in the WPF DataGrid. The following are the issues that I need help:

1) Root Menu Item Header are not bind with ViewModel while the submenu works fine.

2) The submenu always pop up on the left side instead of the right. How can I fix this with style?

<DataGrid.ContextMenu>
<ContextMenu ItemsSource="{Binding PackageCM.Members}" HasDropShadow="True" Placement="Right">
    <ContextMenu.ItemContainerStyle>
        <Style TargetType="MenuItem">
            <Setter Property="Header" Value="{Binding CategoryName}" />
        </Style>
    </ContextMenu.ItemContainerStyle>
    <ContextMenu.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Items}">
            <MenuItem Header="{Binding DisplayName}" Command="{Binding AllPackagesVM.OpenCOBAPackageCommand, Source={StaticResource Locator}}"></MenuItem>
        </HierarchicalDataTemplate>
    </ContextMenu.ItemTemplate>
</ContextMenu>

Root Menu Item Header are not being bind.

Basically, Context Menu is binding to the PackageCM.Members with has a list of Category object and I want to display the CategoryName on the Context Menu root. Following that, Each Category contains a list of Items which will be showed as submenu.

Thanks in advance for help.

1 Answer 1

3

First, your ContextMenu.ItemTemplate definition is incorrect, when you set an ItemSource for ContextMenu you do not define MenuItems yourself because actually ContextMenu will wrap this content inside another MenuItem. So you need to change your template to something like this:

<ContextMenu ItemsSource="{Binding PackageCM.Members}" ...>
    <ContextMenu.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Items}">
            <TextBlock Text="{Binding DisplayName}"></TextBlock >
        </HierarchicalDataTemplate>
    </ContextMenu.ItemTemplate>
</ContextMenu>

You need to put a TextBlock instead of MenuItem because you want to display a text in your ContextMenu menus and bind its Text property to a propety in your model. But so this to work, the model used for root menus and model used for sub-menus must have a property that is named equally, in your case it is DisplayName for sub-menus so in your root menus model must also have a property named DisplayName, This property is bound to Text property of the TextBlock.

You need to do some renaming in your models or introduce an new propety named DisplayName in Category model. So your models would have a common propety something like in this snippet:

// for root menu
public class Category
{
    public string CategoryName { get; }
    public string DisplayName => CategoryName;
    ...
}

// for submenus
public class Item
{
    public string DisplayName { get; }
    ...
}

Hopefully this explanation helps you understand the problem for missing header values.

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

1 Comment

Thank you so much, Redouane. It is working great and now I can see the the ContextMenu shows correctly. Further more, now I understand how the ContextMenu is working with the submenu.

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.