将 MenuItem 中的 CommandParameter 绑定到父 DataGrid [英] Bind CommandParameter from MenuItem to Parent DataGrid

查看:33
本文介绍了将 MenuItem 中的 CommandParameter 绑定到父 DataGrid的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将 MenuItem 中的命令参数绑定到父 Grid DataContext?

How can I bind a command parameter from MenuItem to parent Grid DataContext?

我有一个带有 ContextMenu 的 DataGrid,将菜单项绑定到 ViewModel 命令,但命令参数始终为空.

I have a DataGrid with ContextMenu, binding the menu items to ViewModel commands, but the command parameter is always null.

我在 DataGrid 中使用 Tag 参数来访问 DataContext 并使用所需的命令,但可以弄清楚从每一行获取绑定数据以用作命令参数.

I use Tag parameter into DataGrid to get access into DataContext and use the desired command but could figure it out to get the binding data from every row to use as a command parameter.

我已经在这里查看了很多答案,但找不到任何有效的答案,调用 ViewModel 中的命令参数并且命令参数始终为空.

I had already looked into many answers here, but couldn't find anyone that works, the command parameter inside the ViewModel is called and command parameter is always null.

C#

public class People
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class PeopleWindowViewModel
{
    public List<People> Peoples { get; set; }

    public PeopleWindowViewModel()
    {
        // populate Peoples list...
    }

    public ICommand RemoveCommand
    {
        get
        {
            return RelayCommand.Create((m) =>
            {
                // m always null
            });
        }
    }
}

public class PeoplePage : Page
{
    public PeoplePage()
    {
        InitializeComponent();

        DataContext = new PeopleWindowViewModel();
    }
}

XAML:

  <DataGrid
      Margin="0 8 0 8"
      d:DataContext="{d:DesignInstance local:People}"
      IsReadOnly="True"
      ItemsSource="{Binding Peoples}"
      Tag="{Binding DataContext,
                      RelativeSource={RelativeSource AncestorType={x:Type Page}}}">
    <DataGrid.Columns>
      <DataGridTextColumn
          Binding="{Binding Id}"
          Header="Id" />
      <DataGridTextColumn
          Binding="{Binding Name}"
          Header="Name" />
    </DataGrid.Columns>

    <DataGrid.ContextMenu>
      <ContextMenu
          Tag="{Binding Path=PlacementTarget.Tag,
                              RelativeSource={RelativeSource Self}}">
        <MenuItem
            Command="{Binding PlacementTarget.Tag.RemoveCommand,
                                      RelativeSource={RelativeSource Mode=FindAncestor,
                                                                     AncestorType=ContextMenu}}"
            CommandParameter="{Binding Path=Id,
                                               RelativeSource={RelativeSource Mode=FindAncestor,
                                                                              AncestorType=DataGrid}}"
            Header="Remover" />
      </ContextMenu>
    </DataGrid.ContextMenu>
  </DataGrid>
</Page>

推荐答案

我找到了一个解决方案,但我不确定是否有更好的解决方案.无论如何,你可以这样做:

I found a solution, but I'm not sure if there isn't a better one. Anyway, you can do it like this:

<DataGrid ItemsSource="{Binding Peoples}">
    <DataGrid.Resources>
        <ContextMenu x:Key="ctx_menu">
            <ContextMenu.Resources>
                <Style TargetType="{x:Type MenuItem}">
                    <Setter Property="DataContext" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
                </Style>
            </ContextMenu.Resources>
            <MenuItem Command="{Binding DataContext.RemoveCommand}"
                      CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"
                      Header="Remove" />
        </ContextMenu>
    </DataGrid.Resources>

    <DataGrid.ItemContainerStyle>
        <Style TargetType="{x:Type DataGridRow}">
            <Setter Property="ContextMenu" Value="{StaticResource ctx_menu}" />
        </Style>
    </DataGrid.ItemContainerStyle>

</DataGrid>

这会为您提供整个 People 对象作为 CommandParameter.如果您只需要 Id,只需将 CommandParameter 更改为:

this gives you the whole People object as CommandParameter. If you just want the Id, just change the CommandParameter to:

CommandParameter="{Binding PlacementTarget.DataContext.Id, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"

这篇关于将 MenuItem 中的 CommandParameter 绑定到父 DataGrid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆