I'm aware that there are several posts about how to implement datagrid mutliselection.
I've found the open issue on Github (https://github.com/dotnet/wpf/issues/3140).
The user ice1e0 mentioned a solution with a CustomDataGrid
class.
public class CustomDataGrid : DataGrid
{
public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register(nameof(SelectedItems), typeof(IList), typeof(CustomDataGrid), new PropertyMetadata(default(IList), OnSelectedItemsPropertyChanged));
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
SetValue(SelectedItemsProperty, base.SelectedItems);
}
public new IList SelectedItems
{
get => (IList)GetValue(SelectedItemsProperty);
set => throw new Exception("This property is read-only. To bind to it you must use 'Mode=OneWayToSource'.");
}
private static void OnSelectedItemsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((CustomDataGrid)d).OnSelectedItemsChanged((IList)e.OldValue, (IList)e.NewValue);
}
protected virtual void OnSelectedItemsChanged(IList oldSelectedItems, IList newSelectedItems)
{
}
}
So, I tried to implement it, so I copied the class. And my xaml looks something like that:
<Project1:CustomDataGrid ItemsSource="{Binding Data}" SelectionMode="Extended" SelectionUnit="FullRow" IsReadOnly="True" SelectedItems="{Binding SelectedComputers, Mode=OneWayToSource}" />
and my ViewModel:
[ObservableProperty]
ObservableCollection<string> _selectedComputers;
I use CommunityToolkit.Mvvm (v8.0).
It compiles but SelectedComputers
is null, after I select one or multiple items.
UPDATE:
The issue seems that
void CustomDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.SelectedItemsList = this.SelectedItems;
}
doesn't work. SelectedItemsList
is always null. The problem is mentioned in the other thread: Select multiple items from a DataGrid in an MVVM WPF project
The suggested solution by M463:
this.SelectedItemsList = this.SelectedItems; did not work for me, as SelectedItemsList was always set to null. However, changing the code to foreach (var item in this.SelectedItems) { this.SelectedItemsList.Add(item); } did the trick. Please note, that this requires you to call this.SelectedItemsList.Clear(); in advance, so the items of SelectedItemsList will not get duplicated.
When I try the solution, after selected a row the application crashes with the error:
System.ArgumentException: 'The value "System.Data.DataRowView" is not of type "System.String" and cannot be used in this generic collection.
Parameter name: value'