如何在执行命令之前转换命令参数?

时间:2015-04-08 14:56:55

标签: c# wpf c#-4.0 datagrid wpfdatagrid

我的视图中有一个DataGrid,DataGrid包含带按钮的单元格,这些按钮分配了命令。现在我希望将当前行对象(位于DataGrid.CurrentItem中)传递给命令执行逻辑。

我最初的想法是使用带有值转换器的CommandParameter,其中转换器将DataGrid作为参数并从DataGrid将所需信息提取到我自己的类中 - 这样我将避免从我的视图模型引用DataGrid。

问题是,当显示网格时执行CommandParameter绑定/值转换,这意味着还没有选定的项目。

我可以以某种方式避免将DataGrid引用引入我的命令执行逻辑,比如deffer CommandParameter解析,直到执行Command或类似的东西?

更新:我需要CurrentItem和CurrentColumn,我已经意识到,可以通过绑定SelectedItem来访问CurrentItem,以避免通过提议使用SelectedItem属性来接收答案。

2 个答案:

答案 0 :(得分:3)

  • 您的命令参数应该只是CommandParameter="{Binding}" 这样,参数将是单击按钮的行DataContext,这是您的模型的实例。
  • 在commadns Execute中将参数投射到模型中 方法
  • 例如,您想要阻止命令执行 如果SelectedItem为null或者必须选择Item,则 您只需要从CanExecute方法返回一个bool 无论你想要什么。

答案 1 :(得分:3)

所以我最初的想法足够接近。

当我将CommandParameter绑定到DataGrid时,问题是,当绑定解析时,DataGrid还不知道什么是CurrentColumn或CurrentCell或CurrentItem,因此它正在解析为空值。

所以我将绑定更改为绑定到DataGridCell - 问题解决了 - Cell能够在绑定解析时告诉它所属的列和项目,所以当命令被触发时,它已经拥有了所有正确的数据。

Style看起来像这样:

<Button Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},    
                          Path=DataContext[RowActionFeature].RowActionCommand}"                                                                                                      
        CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridCell}}, 
                                   Converter={StaticResource DataGridCellToRowActionParametersConverter}}">
...
</Button>

转换器是这样的:

public class DataGridCellToRowActionParametersConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var dataGridCell = value as DataGridCell;

        if (dataGridCell == null)
        {
            return null;
        }

        var dataRowView = dataGridCell.DataContext as DataRowView;
        var columnIndex = dataGridCell.Column.DisplayIndex;

        return new RowActionParameters
               {
                   Item = dataGridCell.DataContext,
                   ColumnPropertyName = dataGridCell.Column.SafeAccess(x => x.SortMemberPath),
                   DataRowView = dataRowView,                      
                   ColumnIndex = columnIndex
               };
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}