簡體   English   中英

將CommandParameter從MenuItem綁定到父DataGrid

[英]Bind CommandParameter from MenuItem to Parent DataGrid

如何將命令參數從MenuItem綁定到父Grid DataContext?

我有一個帶有ContextMenu的DataGrid,它將菜單項綁定到ViewModel命令,但是command參數始終為null。

我在DataGrid中使用Tag參數來訪​​問DataContext並使用所需的命令,但是可以弄清楚它從每一行中獲取綁定數據以用作命令參數。

我在這里已經研究了很多答案,但是找不到任何可行的方法,因此調用了ViewModel中的command參數,並且command參數始終為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>

我找到了解決方案,但是不確定是否有更好的解決方案。 無論如何,您可以這樣做:

<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>

編輯:這給您整個人對象作為CommandParameter。 如果只需要Id,只需將CommandParameter更改為:

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

如果必須將ContextMenu保留在UI-LIB的DataGrid中,則必須知道,在您的情況下,這通常是錯誤的做法。 上下文菜單應該轉到您需要...上下文的位置,這就是您的行。 但是無論如何,還是有一些丑陋的“解決方案”。 這是一個:

在您的Xaml中,只需綁定Command並忽略CommandParameter。

<DataGrid ItemsSource="{Binding Peoples}">
    <DataGrid.ContextMenu>
        <ContextMenu>
            <MenuItem Command="{Binding RemoveCommand}"
                      Header="Remove" />
        </ContextMenu>
    </DataGrid.ContextMenu>
</DataGrid>

在您的ICommand方法中,您可以執行以下操作:

private void Remove(object obj)
{
    obj = Mouse.DirectlyOver as FrameworkElement;
    if (obj != null)
        obj = ((FrameworkElement)obj).DataContext;

    // obj should be one People here
}

這在大多數情況下都應該起作用,但是實際上,通常您會盡量避免這種情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM