简体   繁体   中英

C# WPF Context Menu Data Binding

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM