将数据网格上下文菜单的命令参数绑定到选定行的列值
Binding command parameter of data grid context menu to selected row's column value
我有一个绑定到 ObservableCollection 的数据网格。数据网格有一个上下文菜单。单击上下文菜单项时,将触发绑定命令,但我想传递绑定到所选数据网格行的 Id 的命令参数。命令被触发但参数为空。
下面是我试过的代码。
<DataGrid Name="users" ItemsSource="{Binding UsersModel}" CanUserAddRows="False" IsReadOnly="True" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Id}" Header="User Id" Width="auto"/>
<DataGridTextColumn Binding="{Binding Name}" Width="*" Header="User Name"/>
<DataGridTextColumn Binding="{Binding IsRegistered, Converter={StaticResource BoolToYesNoConverter}}" Width="auto" Header="Registered" />
<DataGridTextColumn Binding="{Binding RegisteredOn}" Width="*" Header="Registration Date"/>
</DataGrid.Columns>
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Modify" Command="{Binding Modify}" CommandParameter="{Binding Id}"/>
<MenuItem Header="Delete" Command="{Binding Delete}" CommandParameter="{Binding Id}" />
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
我希望将所选行的 ID 作为命令参数传递。
将 SelectedId
属性 添加到您的视图模型(其中定义了 UsersModel
和命令属性)并绑定 DataGrid 的 SelectedValue
属性 属性.
然后使用SelectedId
进行命令参数绑定。当然要确保 SelectedId
触发 PropertyChanged 事件。
<DataGrid ... SelectedValuePath="Id" SelectedValue="{Binding SelectedId}">
...
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Modify"
Command="{Binding Modify}"
CommandParameter="{Binding SelectedId}"/>
<MenuItem Header="Delete"
Command="{Binding Delete}"
CommandParameter="{Binding SelectedId}" />
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
我会在您的视图模型上创建一个 SelectedRow 属性 以将所选行存储在网格中,然后将上下文菜单项命令绑定到视图模型上引用 SelectedRow 属性 的命令。
我不得不在上下文菜单相关源上使用 PlacementTarget。
// 在视图模型中
public DelegateCommand ModifyCommand { get; }
ModifyCommand = new DelegateCommand(() => { var Id = SelectedRow.Id; //... });
private UsersModel _selectedRow;
public UsersModel SelectedRow
{
get => _selectedRow;
set
{
_selectedRow = value;
OnPropertyChanged(nameof(SelectedRow));
}
}
// 在视图中
DataGrid Name="users" ItemsSource="{Binding Items}" CanUserAddRows="False" IsReadOnly="True" AutoGenerateColumns="False"
SelectedItem="{Binding SelectedRow, Mode=TwoWay}" >
// and on context menu
<MenuItem Header="Modify" Command="{Binding PlacementTarget.DataContext.ModifyCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" />
我假设你的 ViewModel
class 实现了 INotifyPropertyChanged
接口,我假设你实现了触发 属性 变化的方法,我在这里调用这个方法 RaisePropertyChanged
。毕竟,
在您的 viewModel Class:
中定义一个私有字段 selectedUsers
和一个名称为 SelectedUsers
的 属性
private UsersModel selectedUsers;
public UsersModel SelectedUsers
{
get => _selectedFields;
set
{
_selectedFields = value;
Modify.RaiseCanExecuteChanged();
Delete.RaiseCanExecuteChanged();
}
}
添加后,您必须将 SelectionChanged
事件添加到 Grid
,然后在 code-behind set-up 中为您的 seletedUser 设置值,如下所示:
private void usersGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
usersViewModel.SelectedUsers = usersGrid.SelectedItem as UsersModel;
}
并将 DataGrid
的 selectedItem
绑定到 selectedUser
:
<DataGrid Name="users" ItemsSource="{Binding Items}" CanUserAddRows="False"
IsReadOnly="True" AutoGenerateColumns="False"
SelectedItem="{Binding SelectedUser}" >
当您完成这些工作时,selectedUser
可在您的 viewModel 中访问。
我有一个绑定到 ObservableCollection 的数据网格。数据网格有一个上下文菜单。单击上下文菜单项时,将触发绑定命令,但我想传递绑定到所选数据网格行的 Id 的命令参数。命令被触发但参数为空。
下面是我试过的代码。
<DataGrid Name="users" ItemsSource="{Binding UsersModel}" CanUserAddRows="False" IsReadOnly="True" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Id}" Header="User Id" Width="auto"/>
<DataGridTextColumn Binding="{Binding Name}" Width="*" Header="User Name"/>
<DataGridTextColumn Binding="{Binding IsRegistered, Converter={StaticResource BoolToYesNoConverter}}" Width="auto" Header="Registered" />
<DataGridTextColumn Binding="{Binding RegisteredOn}" Width="*" Header="Registration Date"/>
</DataGrid.Columns>
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Modify" Command="{Binding Modify}" CommandParameter="{Binding Id}"/>
<MenuItem Header="Delete" Command="{Binding Delete}" CommandParameter="{Binding Id}" />
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
我希望将所选行的 ID 作为命令参数传递。
将 SelectedId
属性 添加到您的视图模型(其中定义了 UsersModel
和命令属性)并绑定 DataGrid 的 SelectedValue
属性 属性.
然后使用SelectedId
进行命令参数绑定。当然要确保 SelectedId
触发 PropertyChanged 事件。
<DataGrid ... SelectedValuePath="Id" SelectedValue="{Binding SelectedId}">
...
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Modify"
Command="{Binding Modify}"
CommandParameter="{Binding SelectedId}"/>
<MenuItem Header="Delete"
Command="{Binding Delete}"
CommandParameter="{Binding SelectedId}" />
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
我会在您的视图模型上创建一个 SelectedRow 属性 以将所选行存储在网格中,然后将上下文菜单项命令绑定到视图模型上引用 SelectedRow 属性 的命令。 我不得不在上下文菜单相关源上使用 PlacementTarget。
// 在视图模型中
public DelegateCommand ModifyCommand { get; }
ModifyCommand = new DelegateCommand(() => { var Id = SelectedRow.Id; //... });
private UsersModel _selectedRow;
public UsersModel SelectedRow
{
get => _selectedRow;
set
{
_selectedRow = value;
OnPropertyChanged(nameof(SelectedRow));
}
}
// 在视图中
DataGrid Name="users" ItemsSource="{Binding Items}" CanUserAddRows="False" IsReadOnly="True" AutoGenerateColumns="False"
SelectedItem="{Binding SelectedRow, Mode=TwoWay}" >
// and on context menu
<MenuItem Header="Modify" Command="{Binding PlacementTarget.DataContext.ModifyCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" />
我假设你的 ViewModel
class 实现了 INotifyPropertyChanged
接口,我假设你实现了触发 属性 变化的方法,我在这里调用这个方法 RaisePropertyChanged
。毕竟,
在您的 viewModel Class:
selectedUsers
和一个名称为 SelectedUsers
的 属性
private UsersModel selectedUsers;
public UsersModel SelectedUsers
{
get => _selectedFields;
set
{
_selectedFields = value;
Modify.RaiseCanExecuteChanged();
Delete.RaiseCanExecuteChanged();
}
}
添加后,您必须将 SelectionChanged
事件添加到 Grid
,然后在 code-behind set-up 中为您的 seletedUser 设置值,如下所示:
private void usersGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
usersViewModel.SelectedUsers = usersGrid.SelectedItem as UsersModel;
}
并将 DataGrid
的 selectedItem
绑定到 selectedUser
:
<DataGrid Name="users" ItemsSource="{Binding Items}" CanUserAddRows="False"
IsReadOnly="True" AutoGenerateColumns="False"
SelectedItem="{Binding SelectedUser}" >
当您完成这些工作时,selectedUser
可在您的 viewModel 中访问。