如何在执行命令之前转换命令参数?
How to convert command parameter just before command is executed?
我的视图中有一个 DataGrid,DataGrid 有带按钮的单元格,这些按钮已分配了命令。现在我希望将当前行对象(位于 DataGrid.CurrentItem 中)传递给命令执行逻辑。
我最初的想法是将 CommandParameter 与值转换器一起使用,其中转换器会将 DataGrid 作为参数并将所需的信息从 DataGrid 提取到我自己的 class - 这样我就可以避免从我的视图中引用 DataGrid模型。
问题是,在显示网格时执行 CommandParameter binding/value 转换,这意味着还没有选择的项目。
我能否以某种方式避免将 DataGrid 引用引入我的命令执行逻辑中,例如推迟 CommandParameter 解析直到命令执行或类似的事情?
更新:我需要 CurrentItem 和 CurrentColumn,我已经意识到,CurrentItem 可能可以通过 SelectedItem 的绑定访问,所以为了避免收到建议使用 SelectedItem 的答案 属性。
- 你的命令参数应该是
CommandParameter="{Binding}"
这样参数将是单击按钮的行 DataContext
,这是您的模型的一个实例。
- 将您的参数投射到您的 commadns 中的模型
Execute
方法。
- 比如说你想阻止命令的执行
如果 SelectedItem 为 null 或者必须选择 Item,则
您所需要的只是 return 来自
CanExecute
方法的布尔值
随心所欲。
所以我最初的想法很接近。
当我将 CommandParameter 绑定到 DataGrid 时,问题是,当绑定解析时,DataGrid 还不知道 CurrentColumn、CurrentCell 或 CurrentItem 是什么,所以它解析为空值。
所以我更改了绑定以改为绑定到 DataGridCell - 问题解决了 - Cell 能够在绑定解析时间告诉它它属于的列和项目,所以当命令被触发时,它具有所有正确的数据已经.
样式看起来像这样:
<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();
}
}
我的视图中有一个 DataGrid,DataGrid 有带按钮的单元格,这些按钮已分配了命令。现在我希望将当前行对象(位于 DataGrid.CurrentItem 中)传递给命令执行逻辑。
我最初的想法是将 CommandParameter 与值转换器一起使用,其中转换器会将 DataGrid 作为参数并将所需的信息从 DataGrid 提取到我自己的 class - 这样我就可以避免从我的视图中引用 DataGrid模型。
问题是,在显示网格时执行 CommandParameter binding/value 转换,这意味着还没有选择的项目。
我能否以某种方式避免将 DataGrid 引用引入我的命令执行逻辑中,例如推迟 CommandParameter 解析直到命令执行或类似的事情?
更新:我需要 CurrentItem 和 CurrentColumn,我已经意识到,CurrentItem 可能可以通过 SelectedItem 的绑定访问,所以为了避免收到建议使用 SelectedItem 的答案 属性。
- 你的命令参数应该是
CommandParameter="{Binding}"
这样参数将是单击按钮的行DataContext
,这是您的模型的一个实例。 - 将您的参数投射到您的 commadns 中的模型
Execute
方法。 - 比如说你想阻止命令的执行
如果 SelectedItem 为 null 或者必须选择 Item,则
您所需要的只是 return 来自
CanExecute
方法的布尔值 随心所欲。
所以我最初的想法很接近。
当我将 CommandParameter 绑定到 DataGrid 时,问题是,当绑定解析时,DataGrid 还不知道 CurrentColumn、CurrentCell 或 CurrentItem 是什么,所以它解析为空值。
所以我更改了绑定以改为绑定到 DataGridCell - 问题解决了 - Cell 能够在绑定解析时间告诉它它属于的列和项目,所以当命令被触发时,它具有所有正确的数据已经.
样式看起来像这样:
<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();
}
}