如何在DataGrid中的多个选定行上执行命令?

问题描述:

我有一个数据网格与上下文菜单使用命令几个菜单选项。目前它只允许我一次运行一行命令,我希望能够在单击菜单项时运行命令所有选定的行。我想使用命令,因为我们使用CanExecute来启用/禁用命令,但如果没有其他选项,我将使用Click如何在DataGrid中的多个选定行上执行命令?

这是当前的实现,一次只允许1行。

<DataGrid.RowStyle> 
    <Style TargetType="{x:Type DataGridRow}"> 
     <Setter Property="ContextMenu"> 
     <Setter.Value> 
      <ContextMenu> 
       <MenuItem Visibility="Visible" 
         Header="{Binding Path=ApplicationStrings.LaunchItemLabel, 
              Source={StaticResource ResourceWrapper}}" 
         Command="{StaticResource launchCommand}" 
         CommandParameter="{Binding}" /> 

[绑定你的DataGrid的视图模型属性selectedItems属性,然后访问您的launchCommand,而不是使用CommandParameter回传你的SelectedItem。 ]

编辑:道歉,我忘记了SelectedItems属性只读,不能修改无法绑定。

山姆workaround你提到的应该做的工作,否则下面的作品,以及:

的想法是绑定的DataRow的IsSelected来(在我的例子MyClass的)一个在DataItem的财产,然后在命令处理程序,遍历集合并检查IsSelected属性。

的XAML:

<Window.DataContext> 
    <local:ViewModel /> 
</Window.DataContext> 

<Window.Resources> 
    <local:BindingProxy x:Key="DataContextProxy" Data="{Binding}" /> 
</Window.Resources> 

<Grid> 
    <DataGrid ItemsSource="{Binding MyRows}" > 
     <DataGrid.Resources> 
      <Style TargetType="{x:Type DataGridRow}"> 
       <Setter Property="IsSelected" Value="{Binding IsSelected}" /> 
       <Setter Property="ContextMenu"> 
        <Setter.Value> 
         <ContextMenu> 
          <MenuItem Visibility="Visible" Header="Launch" 
             Command="{Binding Data.LaunchCommand, Source={StaticResource DataContextProxy}}" /> 
         </ContextMenu> 
        </Setter.Value> 
       </Setter> 
      </Style> 
     </DataGrid.Resources> 
    </DataGrid> 
</Grid> 

视图模型:

public class ViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    private void OnPropertyChanged(string propertyName) 
    { 
     if (this.PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    private ObservableCollection<MyClass> _myRows = new ObservableCollection<MyClass>(); 
    public ObservableCollection<MyClass> MyRows { get { return _myRows; } set { _myRows = value; OnPropertyChanged("MyRuns"); } } 

    private ICommand _launchCommand; 
    public ICommand LaunchCommand { get { return _launchCommand; } private set { _launchCommand = value; OnPropertyChanged("LaunchCommand"); } } 

    public ViewModel() 
    { 
     MyRows = new ObservableCollection<MyClass>() 
     { 
      new MyClass() { Text = "Example Line 1" }, 
      new MyClass() { Text = "Example Line 2" }, 
      new MyClass() { Text = "Example Line 3" } 

     }; 

     LaunchCommand = new ActionCommand(Launch); 

    } 

    private void Launch() 
    { 
     foreach (var row in MyRows) 
     { 
      if (row.IsSelected) 
      { 
       //... 
      } 
     } 
    } 
} 

public class MyClass : INotifyPropertyChanged 
{ 
    private string _text; 
    public string Text { get { return _text; } set { _text = value; OnPropertyChanged("Text"); } } 

    private bool _isSelected; 
    public bool IsSelected { get { return _isSelected; } set { _isSelected = value; OnPropertyChanged("IsSelected"); } } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void OnPropertyChanged(string propertyName) 
    { 
     if (this.PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

// http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/ 
public class BindingProxy : Freezable 
{ 
    protected override Freezable CreateInstanceCore() 
    { 
     return new BindingProxy(); 
    } 

    public object Data { get { return (object)GetValue(DataProperty); } set { SetValue(DataProperty, value); } } 
    public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null)); 
} 

public class ActionCommand : ICommand 
{ 
    public event EventHandler CanExecuteChanged; 

    private Action _action; 

    public ActionCommand(Action action) 
    { 
     _action = action; 
    } 

    public bool CanExecute(object parameter) { return true; } 

    public void Execute(object parameter) 
    { 
     if (_action != null) 
      _action(); 
    } 
} 
+0

谢谢你,让我给一个尝试。我发现[此链接](http://blog.functionalfun.net/2009/02/how-to-databind-to-selecteditems.html),如果它能起作用,我会发布为答​​案 – Darren 2013-03-14 15:28:46