Reputation: 550
I have a DataGrid with virtualization enabled and are trying to get multi-select to work.
I have defined DataGrid.ItemContainerStyle
<DataGrid.ItemContainerStyle >
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"></Setter>
</Style>
Everything works fine if virtualization is disabled or if I don't scroll, but it stops working as soon as i scroll with virtualization enabled and DataGridRows goes out and in from memory. The IsSelected property stops setting IsSelected on my view models.
I have also tried to create a DependencyProperty to try to handle it my self. But random events are sent once I start to scroll with rows selected. A row I have not selected are for example sometimes called and the events are triggered multiple times.
I feel like this is something that should work by defualt. Do you know if multiselection should work and do you have any ideas of how I can resolve this?
Upvotes: 1
Views: 822
Reputation: 550
I solved it by creating a dependency property
public static class DataGridSelectedItemsDependencyProperty
{
public static readonly DependencyProperty SelectedItemsChangedHandlerProperty =
DependencyProperty.RegisterAttached("SelectedItemsChangedHandler",
typeof(ICommand),
typeof(DataGridSelectedItemsDependencyProperty),
new FrameworkPropertyMetadata(OnSelectedItemsChangedHandlerChanged));
public static ICommand GetSelectedItemsChangedHandler(DependencyObject element)
{
if (element == null)
throw new ArgumentNullException(nameof(element));
return element.GetValue(SelectedItemsChangedHandlerProperty) as ICommand;
}
public static void SetSelectedItemsChangedHandler(DependencyObject element, ICommand value)
{
if (element == null)
throw new ArgumentNullException(nameof(element));
element.SetValue(SelectedItemsChangedHandlerProperty, value);
}
private static void OnSelectedItemsChangedHandlerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var dataGrid = (DataGrid)d;
if (e.OldValue == null && e.NewValue != null)
dataGrid.SelectionChanged += ItemsControl_SelectionChanged;
if (e.OldValue != null && e.NewValue == null)
dataGrid.SelectionChanged -= ItemsControl_SelectionChanged;
}
private static void ItemsControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var dataGrid = (DataGrid)sender;
var itemsChangedHandler = GetSelectedItemsChangedHandler(dataGrid);
itemsChangedHandler.Execute(dataGrid.SelectedItems);
}
}
That I use like this in my view (xaml)
<DataGrid
dependencyProperties:DataGridSelectedItemsDependencyProperty.SelectedItemsChangedHandler="{Binding SelectedItemsChanged}"
Upvotes: 1