Wpf datagrid mvvm multi select
//xaml <Window x:Class="WpfApp39.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp39" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" mc:Ignorable="d" WindowState="Maximized" Title="MainWindow" Height="450" Width="800"> <Window.Resources> <Style TargetType="DataGridRow"> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="FontSize" Value="30"/> <Setter Property="FontWeight" Value="ExtraBold"/> <Setter Property="Foreground" Value="Red"/> </Trigger> </Style.Triggers> </Style> </Window.Resources> <Grid> <DataGrid x:Name="dg" ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectionMode="Extended" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Blue" BorderThickness="5"> <i:Interaction.Triggers> <i:EventTrigger EventName="SelectionChanged"> <i:InvokeCommandAction Command="{Binding SelectedMultiCommand}" CommandParameter="{Binding ElementName=dg,Path=SelectedItems}"/> </i:EventTrigger> </i:Interaction.Triggers> </DataGrid> </Grid> </Window> //xaml.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApp39 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); MainVM vm = new MainVM(); this.DataContext = vm; } } } //viewmodel using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; namespace WpfApp39 { public class MainVM : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propName) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propName)); } } public MainVM() { InitItemsSource(); } private void InitItemsSource() { BooksCollection = new ObservableCollection<Book>(); for(int i=0;i<10000;i++) { BooksCollection.Add(new Book() { Id=i+1, Title=$"Title__{Guid.NewGuid()}", ISBN=$"ISBN__{Guid.NewGuid()}", Name=$"Name_{Guid.NewGuid()}" }); } } private ObservableCollection<Book> booksCollection; public ObservableCollection<Book> BooksCollection { get { return booksCollection; } set { if (value != booksCollection) { booksCollection = value; OnPropertyChanged("BooksCollection"); } } } private ObservableCollection<Book> selectedBooksCollection; public ObservableCollection<Book> SelectedBooksCollection { get { return selectedBooksCollection; } set { if(value != selectedBooksCollection) { selectedBooksCollection = value; OnPropertyChanged("SelectedBooksCollection"); } } } private DelegateCmd selectedMultiCommand; public DelegateCmd SelectedMultiCommand { get { if (selectedMultiCommand == null) { selectedMultiCommand = new DelegateCmd(SelectedMultiCommandExecuted); } return selectedMultiCommand; } } private void SelectedMultiCommandExecuted(object obj) { System.Collections.IList tempIList = obj as System.Collections.IList; if (tempIList != null && tempIList.Count > 0) { SelectedBooksCollection = new ObservableCollection<Book>(); foreach (var item in tempIList) { Book tempBk = item as Book; if(tempBk != null) { SelectedBooksCollection.Add(tempBk); } } } StringBuilder builder = new StringBuilder(); foreach (var item in SelectedBooksCollection) { builder.AppendLine($"{item.Id},{item.Name}"); } System.Windows.MessageBox.Show($"Selected {SelectedBooksCollection.Count} items","Information",MessageBoxButton.OK,MessageBoxImage.Information); } } public class Book { public int Id { get; set; } public string Name { get; set; } public string ISBN { get; set; } public string Title { get; set; } } public class DelegateCmd : ICommand { private readonly Action<object> _execute; private readonly Predicate<object> _canExecute; public DelegateCmd(Action<object> executeValue, Predicate<object> canExecuteValue) { _execute = executeValue; _canExecute = canExecuteValue; } public DelegateCmd(Action<object> executeValue) : this(executeValue, null) { } public event EventHandler CanExecuteChanged; public void RaiseCanExecuteChanged() { if (CanExecuteChanged != null) { CanExecuteChanged(this, EventArgs.Empty); } } public bool CanExecute(object parameter) { if (_canExecute == null) { return true; } return _canExecute(parameter); } public void Execute(object parameter) { _execute(parameter); } } }
1.The key located at
//Install System.Windows.Interactivity and reference it in xaml xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
2.
//Interaction.Triggers,EventTrigger,EventName InvokeCommandAction <DataGrid x:Name="dg" ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectionMode="Extended" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Blue" BorderThickness="5"> <i:Interaction.Triggers> <i:EventTrigger EventName="SelectionChanged"> <i:InvokeCommandAction Command="{Binding SelectedMultiCommand}" CommandParameter="{Binding ElementName=dg,Path=SelectedItems}"/> </i:EventTrigger> </i:Interaction.Triggers>
3.Convert SelectedItemCollection to System.Collection.IList,then to the ObservableCollection
private void SelectedMultiCommandExecuted(object obj) { System.Collections.IList tempIList = obj as System.Collections.IList; if (tempIList != null && tempIList.Count > 0) { SelectedBooksCollection = new ObservableCollection<Book>(); foreach (var item in tempIList) { Book tempBk = item as Book; if(tempBk != null) { SelectedBooksCollection.Add(tempBk); } } }
}