C# WPF 上下文菜单数据绑定
C# WPF Context Menu Data Binding
我正在尝试在 WPF DataGrid 中创建动态上下文菜单。以下是我需要帮助的问题:
1) 子菜单工作正常时,根菜单项 Header 未与 ViewModel 绑定。
2) 子菜单总是弹出在左侧而不是右侧。我怎样才能用样式解决这个问题?
<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.
基本上,上下文菜单绑定到 PackageCM.Members,具有类别列表 object,我想在上下文菜单根目录中显示类别名称。接下来,每个类别都包含一个项目列表,这些项目将显示为子菜单。
在此先感谢您的帮助。
首先,您的 ContextMenu.ItemTemplate
定义不正确,当您为 ContextMenu 设置 ItemSource 时,您没有自己定义 MenuItems,因为实际上 ContextMenu 会将此内容包装在另一个 MenuItem 中。所以你需要把你的模板改成这样:
<ContextMenu ItemsSource="{Binding PackageCM.Members}" ...>
<ContextMenu.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Items}">
<TextBlock Text="{Binding DisplayName}"></TextBlock >
</HierarchicalDataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
您需要放置 TextBlock
而不是 MenuItem
,因为您想在 ContextMenu
菜单中显示文本并绑定其 Text
属性到模型中的属性。但是这样才能工作,用于根菜单的模型和用于 sub-menus 的模型必须有一个相同命名的 属性,在你的情况下它是 DisplayName
for sub-menus所以在你的根菜单模型中也必须有一个名为 DisplayName
的 属性,这个 属性 绑定到 TextBlock
.
的文本 属性
您需要在您的模型中进行一些重命名或在 Category
模型中引入一个名为 DisplayName
的新属性。所以你的模型会有一个共同的属性,就像这个片段:
// for root menu
public class Category
{
public string CategoryName { get; }
public string DisplayName => CategoryName;
...
}
// for submenus
public class Item
{
public string DisplayName { get; }
...
}
希望此解释能帮助您理解缺少 header 值的问题。
我正在尝试在 WPF DataGrid 中创建动态上下文菜单。以下是我需要帮助的问题:
1) 子菜单工作正常时,根菜单项 Header 未与 ViewModel 绑定。
2) 子菜单总是弹出在左侧而不是右侧。我怎样才能用样式解决这个问题?
<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.
基本上,上下文菜单绑定到 PackageCM.Members,具有类别列表 object,我想在上下文菜单根目录中显示类别名称。接下来,每个类别都包含一个项目列表,这些项目将显示为子菜单。
在此先感谢您的帮助。
首先,您的 ContextMenu.ItemTemplate
定义不正确,当您为 ContextMenu 设置 ItemSource 时,您没有自己定义 MenuItems,因为实际上 ContextMenu 会将此内容包装在另一个 MenuItem 中。所以你需要把你的模板改成这样:
<ContextMenu ItemsSource="{Binding PackageCM.Members}" ...>
<ContextMenu.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Items}">
<TextBlock Text="{Binding DisplayName}"></TextBlock >
</HierarchicalDataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
您需要放置 TextBlock
而不是 MenuItem
,因为您想在 ContextMenu
菜单中显示文本并绑定其 Text
属性到模型中的属性。但是这样才能工作,用于根菜单的模型和用于 sub-menus 的模型必须有一个相同命名的 属性,在你的情况下它是 DisplayName
for sub-menus所以在你的根菜单模型中也必须有一个名为 DisplayName
的 属性,这个 属性 绑定到 TextBlock
.
您需要在您的模型中进行一些重命名或在 Category
模型中引入一个名为 DisplayName
的新属性。所以你的模型会有一个共同的属性,就像这个片段:
// for root menu
public class Category
{
public string CategoryName { get; }
public string DisplayName => CategoryName;
...
}
// for submenus
public class Item
{
public string DisplayName { get; }
...
}
希望此解释能帮助您理解缺少 header 值的问题。