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

C# 如何在执行命令之前转换命令参数?,c#,wpf,c#-4.0,datagrid,wpfdatagrid,C#,Wpf,C# 4.0,Datagrid,Wpfdatagrid,我的视图中有一个DataGrid,DataGrid有带按钮的单元格,这些单元格分配了命令。现在我希望将当前行对象(位于DataGrid.CurrentItem中)传递给命令执行逻辑 我最初的想法是将CommandParameter与值转换器一起使用,转换器将DataGrid作为参数,并将所需信息从DataGrid提取到我自己的类中——这样我就可以避免从视图模型中引用DataGrid 问题是,显示网格时会执行CommandParameter绑定/值转换,这意味着还并没有选定的项 我是否可以避免将D

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

我最初的想法是将CommandParameter与值转换器一起使用,转换器将DataGrid作为参数,并将所需信息从DataGrid提取到我自己的类中——这样我就可以避免从视图模型中引用DataGrid

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

我是否可以避免将DataGrid引用引入到命令执行逻辑中,比如在执行命令之前解析deffer CommandParameter之类的内容

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

  • 您的命令参数应该是
    CommandParameter=“{Binding}”
    这样,参数将是单击按钮的行
    DataContext
    ,该按钮是模型的一个实例
  • 将参数强制转换到命令中的模型
    Execute
    方法
  • 例如,假设您希望阻止该命令执行 如果SelectedItem为空或必须选择该项,则 您只需从基于方法的
    CanExecute
    返回bool即可 你想买什么就买什么
      • 您的命令参数应该是
        CommandParameter=“{Binding}”
        这样,参数将是单击按钮的行
        DataContext
        ,该按钮是模型的一个实例
      • 将参数强制转换到命令中的模型
        Execute
        方法
      • 例如,假设您希望阻止该命令执行 如果SelectedItem为空或必须选择该项,则 您只需从基于方法的
        CanExecute
        返回bool即可 你想买什么就买什么

        • 所以我最初的想法非常接近

          当我将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();
              }
          }
          

          所以我最初的想法很接近

          当我将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();
              }
          }
          


          你试过了吗,我想绑定是在你触发命令时执行的。@Bolu-是的,我试过了,绑定是在呈现数据网格时执行的,而不是在单击按钮时执行的。你想发送什么命令参数,我想大部分都可以通过按钮的命令绑定来完成。我不知道这是WPF,还有一个C标记。你试过了吗,我认为绑定是在您触发命令时执行的。@Bolu-是的,我已经尝试过了,绑定是在呈现数据网格时执行的,而不是在单击按钮时执行的。您要发送什么命令参数,我想大部分都可以通过按钮的命令绑定来完成。我不知道这是WPF。还有一个C#标记。它解决了CurrentItem问题,但没有回答如何获取CurrentColumn。@Giedrius您在同一行中有多个按钮使用同一命令?是的,我使用DataGridCell样式,所以样式是按钮,它的命令被描述-所以是的,我需要以某种方式识别它是什么按钮。@Giedrius确定您可以使用
          IMultiValueConverter
          向您的命令传递多个参数,例如,您可以将列索引作为附加参数传递,我不确定在没有看到XAML的情况下你到底想做什么,所以请用其中的相关部分更新问题,同时ViewModel必须对你的视图一无所知,使用XAML和Converters一切都是可行的我明白你的意思,我想我还没有很好地表达我的问题-主要的想法是,如果可以将CommandParameter解析推迟到command即将执行的时刻,而不是在渲染时进行解析。这解决了CurrentItem问题,但不回答如何获取CurrentColumn。@Giedrius您在同一行中有多个按钮,使用同一命令?是的,我使用DataGridCell样式,因此样式中是button,并且描述了它的命令-是的,我需要以某种方式识别按钮。@Giedrius确定您可以使用
          IMultiValueConverter
          向命令传递多个参数。例如,您可以将列索引作为附加参数传递,我不确定您在没有看到XAML的情况下到底想做什么,因此请使用问题的相关部分更新问题,另外,ViewModel对您的视图一无所知,使用XAML和Converters一切都是可行的。我明白您的意思,我想我还没有很好地阐述我的问题——主要的想法是,是否可以将命令参数解析推迟到命令即将执行时,而不是在渲染时进行解析。