【发布时间】:2020-09-21 21:59:55
【问题描述】:
我知道以前有人问过这个问题,但我无法使用最少的代码示例。我要求对整个事情进行审查。
我有一个显示一堆行的 WPF DataGrid。每行都有一个右键单击 ContextMenu 及其自己的命令。
我无法正确设置 ContextMenu 部分。它抱怨“ContextMenu 不能有逻辑或视觉父级”。任何帮助将不胜感激。
谢谢。
-
XAML 文件:
<DataGrid ItemsSource="{Binding MyModules}" AutoGenerateColumns="False"> <!-- Begin uncertain part --> <ContextMenu ItemsSource="{Binding Configuration.Commands}"> <ContextMenu.ItemContainerStyle> <Style TargetType="x:Type ContextMenuItem"> <Setter Property="Command" Value="Binding Command}" /> </Style> </ContextMenu.ItemContainerStyle> </ContextMenu> <!-- End uncertain part --> <DataGrid.Columns> <DataGridTemplateColumn Header="Module Name" Width="*" IsReadOnly="True"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Configuration.Name}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="Module Description" Width="3*" IsReadOnly="True"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Configuration.Description}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> -
ViewModel 文件:
public ObservableCollection<IModule> MyModules { get; set; } // ... public interface IModule { Configuration Configuration { get; } void ExecuteCommand(Command command); } public class Configuration { public Guid Id { get; private set; } public string Name { get; private set; } public string Description { get; private set; } public List<Command> Commands = new List<Command>(); public Configuration(string name, string description, List<Command> commands) { Id = new Guid(); Name = name; Description= description; Commands = commands; } }
编辑 1:
我从很多地方得到了样本。现在它编译了。但是,右键单击上下文菜单完全是空的。
<DataGrid ItemsSource="{Binding MyModules}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Configuration Name" Width="*" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Configuration.Name}">
<TextBlock.ContextMenu>
<ContextMenu ItemsSource="{Binding Configuration.Commands}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Command" Value="{Binding ItemAction}" />
<Setter Property="Header" Value="{Binding ItemHeader}" />
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Description" Width="3*" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Configuration.MainMenuDescription}">
<TextBlock.ContextMenu>
<ContextMenu ItemsSource="{Binding Configuration.Commands}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Command" Value="{Binding ItemAction}" />
<Setter Property="Header" Value="{Binding ItemHeader}" />
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
虽然我不太喜欢第二种方法。我不得不为每一列复制 ContextMenu 标记...
【问题讨论】:
-
尝试在您的 {Binding Configuration.Commands} 中添加一些虚拟转换器,看看您实际得到了什么。可能是你什么都没有(也许你初始化你的集合较晚并且你没有实现 INotifyPropertyChanged),或者你的 ContextMenu 不共享 TextBlock 的 DataContext。
-
@o_w:谢谢你的建议。 DataContext 很好,ViewModel 是正确的。这只是我正在寻找的一些 XAML 语法。 mm8 通过 ItemContainerStyle 方法为我解决了这个问题。
标签: wpf xaml dynamic datagrid contextmenu