将CommandParameter从MenuItem绑定到父DataGrid [英] Bind CommandParameter from MenuItem to Parent DataGrid
问题描述
如何将MenuItem中的命令参数绑定到父Grid DataContext?
How can I bind a command parameter from MenuItem to parent Grid DataContext?
我有一个带有ContextMenu的DataGrid,它将菜单项绑定到ViewModel命令,但是command参数始终为null.
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:
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}}}"
这篇关于将CommandParameter从MenuItem绑定到父DataGrid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!