在上下文菜单命令参数mvvm中获取行

时间:2015-03-31 06:21:08

标签: wpf mvvm binding datatable datarow

我已将DataTable设置为WPF DataGrid的ItemsSource。 现在我有一个上下文菜单来删除任何行。该命令在具有DataTable对象的视图模型中处理。但我需要提升命令的行。怎么做到呢? 什么是命令参数?

1 个答案:

答案 0 :(得分:0)

由于ContextMenu不是可视化树的一部分,我们需要创建一个Freezable作为代理,以便能够联系DataGrid以获取所选行。 这是一个快速而又脏的代理。您可以更改属性类型以匹配您的datacontext类型,以使设计时绑定验证工作:

class DataContextProxy : Freezable
{
    public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(DataContextProxy));


    //Change this type to match your ViewModel Type/Interface
    //Then IntelliSense will help with binding validation
    public object Data 
    {
        get { return GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    protected override Freezable CreateInstanceCore()
    {
        return new DataContextProxy();
    }
}

然后在DataGrid上设置它:

<DataGrid x:Name="grdData">
    <DataGrid.Resources>
        <DataContextProxy x:Key="Proxy"
                          Data="{Binding ElementName=grdData}"/>
    </DataGrid.Resources>
    <DataGrid.ContextMenu>
        <ContextMenu>
            <MenuItem Command="{Binding DeleteCommand}"
                      CommandParameter="{Binding Data.SelectedItems, Source={StaticResource Proxy}"
                      Header="Delete"/>
       </ContextMenu>
   </DataGrid.ContextMenu>     

现在在viewModel中,在DeleteCommand CanExecuteExecute处理程序中:

private bool DeleteCanExecute(object obj)
{
    var rows = obj as IList;
    if (rows == null)
        return false;
    if (rows.Count == 0)
        return false;
    return rows.OfType<DataRowView>().Any();
}
private void DeleteExecute(object obj)
{
    var rows = obj as IList;
    if (rows != null)
        foreach (DataRowView rowView in rows)
        {
            var row = rowView.Row;
            //Handle deletion
        }
}