![](/img/trans.png)
[英]WPF DataGrid - bind dataitem's property as CommandParameter
[英]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.