WPF DataGrid:单独行的动态生成的ContextMenu

问题描述

我知道之前曾有人问过这个问题,但是我无法解决最少的代码示例。我要求对整件事进行审查。

我有一个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标记...

解决方法

您可以定义一个ItemContainerStyle,在其中为所有行设置ContextMenu属性:

<DataGrid ItemsSource="{Binding MyModules}" AutoGenerateColumns="False">
    <DataGrid.ItemContainerStyle>
        <Style TargetType="DataGridRow">
            <Setter Property="ContextMenu">
                <Setter.Value>
                    <ContextMenu ItemsSource="{Binding Configuration.Commands}">
                        <ContextMenu.ItemContainerStyle>
                            <Style TargetType="{x:Type ContextMenuItem}">
                                <Setter Property="Command" Value="{Binding Command}" />
                            </Style>
                        </ContextMenu.ItemContainerStyle>
                    </ContextMenu>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.ItemContainerStyle>


    <DataGrid.Columns>
        ...
    </DataGrid.Columns>
</DataGrid>