Wpf 将数据网格上下文菜单的命令参数绑定到选定行';s列值

Wpf 将数据网格上下文菜单的命令参数绑定到选定行';s列值,wpf,data-binding,datagrid,contextmenu,Wpf,Data Binding,Datagrid,Contextmenu,我有一个数据网格绑定到一个ObservableCollection。数据网格有一个上下文菜单。单击上下文菜单项时,将触发绑定命令,但我希望传递绑定到所选数据网格行Id的命令参数。命令被触发,但参数为null 下面是我尝试过的代码 <DataGrid Name="users" ItemsSource="{Binding UsersModel}" CanUserAddRows="False" IsReadOnly="True" AutoGenerateColumns="False">

我有一个数据网格绑定到一个ObservableCollection。数据网格有一个上下文菜单。单击上下文菜单项时,将触发绑定命令,但我希望传递绑定到所选数据网格行Id的命令参数。命令被触发,但参数为null

下面是我尝试过的代码

 <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
进行CommandParameter绑定。当然,确保
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>

...

我会在viewmodel上创建一个SelectedRow属性,将选定行存储在网格中,然后将上下文菜单项命令绑定到viewmodel上引用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}}}" />
DataGrid Name=“users”ItemsSource=“{Binding Items}”CanUserAddRows=“False”IsReadOnly=“True”AutoGenerateColumns=“False”
SelectedItem=“{Binding SelectedRow,Mode=TwoWay}”>
//和在上下文菜单上

我假设您的
ViewModel
类实现了
INotifyPropertyChanged
接口,并且我假设您实现了一个触发属性更改的方法,这里我称此方法为
RaisePropertyChanged
。在这一切之后, 在viewModel类中定义一个私有字段
selectedUsers
和一个名为
selectedUsers
的属性:

private UsersModel selectedUsers;

public UsersModel SelectedUsers
    {
        get => _selectedFields;

        set
        {
            _selectedFields = value;
            Modify.RaiseCanExecuteChanged();
            Delete.RaiseCanExecuteChanged();
        }
    }
添加后,必须将
SelectionChanged
事件添加到
网格
,然后在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中是可访问的。

尝试将命令参数设置为“yay”,您将看到它正在进行。这个问题与上下文菜单具有其on-datacontext这一事实有关。据我所知,“Modify”是我的ICommand属性。My window datacontext设置为UsersViewModel,items source绑定到UsersModel,UsersModel是一种ObservableCollection类型。在哪个类中定义了“Modify”属性?@mm8“命令被触发”,因此命令属性显然是在UsersModel属性所在的主视图模型级别定义的<代码>{Binding Id}显然在那里不起作用。请注意,在SelectedItem绑定上设置
Mode=TwoWay
是多余的。默认情况下,它已经双向绑定。