Datagrid Virtualization affect Selection of items

663 views Asked by At

I have a datagrid that shows large number of data so I turn on the virtualization. On my grid I also have a checkbox column that is bind two-way on IsSelected property of my viewmodel. When I tried to Select All, all items are selected. When I selected one row, the row is the only selected on the visible area. But when I scroll down, the other items are still selected. The desired behavior should be the selected row should be the only selected item on the grid. I think virtualization does not handle this scenario. How can I solve this issue?

Here's my code:

View

<Window x:Class="TestSelection.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:testSelection="clr-namespace:TestSelection"
        Title="MainWindow" Height="500" Width="200">
    <Window.DataContext>
        <testSelection:ViewModel/>
    </Window.DataContext>
    <Window.Resources>
        <DataTemplate x:Key="CheckBoxRowHeaderCell">
            <Grid>
                <CheckBox IsChecked="{Binding Path=DataContext.IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
                            RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}}"/>
            </Grid>
        </DataTemplate>
    </Window.Resources>
    <DataGrid ItemsSource="{Binding Items}"
            RowHeight="20" MaxHeight="500" Width="Auto" ColumnWidth="*"
            AutoGenerateColumns="False" IsReadOnly="True"
            SelectionMode="Extended" SelectionUnit="FullRow"
            CanUserResizeRows="False"
            HeadersVisibility="All"
            EnableRowVirtualization="True"
            VirtualizingStackPanel.VirtualizationMode ="Standard"
            VirtualizingStackPanel.IsVirtualizing ="True"
            RowHeaderTemplate="{DynamicResource CheckBoxRowHeaderCell}">
            <DataGrid.ItemContainerStyle>
                <Style TargetType="{x:Type DataGridRow}">
                    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                </Style>
            </DataGrid.ItemContainerStyle>
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
            </DataGrid.Columns>
    </DataGrid>
</Window>

Model

public class SampleItem : INotifyPropertyChanged
{

    private bool p1;
    private string p2;

    public SampleItem(bool p1, string p2)
    {
        IsSelected = p1;
        Name = p2;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaiseNotifyPropertyChanged(string property)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(property));
        }
    }

    private bool isSelected = false;
    /// <summary>
    /// Sets and gets the IsSelected property.
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary>
    public bool IsSelected
    {
        get
        {
            return isSelected;
        }

        set
        {
            if (isSelected == value)
            {
                return;
            }

            isSelected = value;
            RaiseNotifyPropertyChanged("IsSelected");
        }
    }

    private string name = string.Empty;
    /// <summary>
    /// Sets and gets the Name property.
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary>
    public string Name
    {
        get
        {
            return name;
        }

        set
        {
            if (name == value)
            {
                return;
            }

            name = value;
            RaiseNotifyPropertyChanged("Name");
        }
    }
}

ViewModel

public class ViewModel : INotifyPropertyChanged
{
    public ObservableCollection<SampleItem> Items
    {
        get
        {
            return new ObservableCollection<SampleItem>()
            {
                new SampleItem(true, "1"), new SampleItem(true, "2"), new SampleItem(true, "3"), new SampleItem(true, "4"),
                new SampleItem(true, "4"), new SampleItem(true, "5"), new SampleItem(true, "6"), new SampleItem(true, "7"),
                new SampleItem(true, "1"), new SampleItem(true, "2"), new SampleItem(true, "3"), new SampleItem(true, "4"),
                new SampleItem(true, "4"), new SampleItem(true, "5"), new SampleItem(true, "6"), new SampleItem(true, "7"),
                new SampleItem(true, "1"), new SampleItem(true, "2"), new SampleItem(true, "3"), new SampleItem(true, "4"),
                new SampleItem(true, "4"), new SampleItem(true, "5"), new SampleItem(true, "6"), new SampleItem(true, "7"),
                new SampleItem(true, "1"), new SampleItem(true, "2"), new SampleItem(true, "3"), new SampleItem(true, "4"),
                new SampleItem(true, "4"), new SampleItem(true, "5"), new SampleItem(true, "6"), new SampleItem(true, "7"),
                new SampleItem(true, "1"), new SampleItem(true, "2"), new SampleItem(true, "3"), new SampleItem(true, "4"),
                new SampleItem(true, "4"), new SampleItem(true, "5"), new SampleItem(true, "6"), new SampleItem(true, "7"),
                new SampleItem(true, "1"), new SampleItem(true, "2"), new SampleItem(true, "3"), new SampleItem(true, "4"),
                new SampleItem(true, "4"), new SampleItem(true, "5"), new SampleItem(true, "6"), new SampleItem(true, "7"),
                new SampleItem(true, "1"), new SampleItem(true, "2"), new SampleItem(true, "3"), new SampleItem(true, "4"),
                new SampleItem(true, "4"), new SampleItem(true, "5"), new SampleItem(true, "6"), new SampleItem(true, "7"),
                new SampleItem(true, "1"), new SampleItem(true, "2"), new SampleItem(true, "3"), new SampleItem(true, "4"),
                new SampleItem(true, "4"), new SampleItem(true, "5"), new SampleItem(true, "6"), new SampleItem(true, "7"),
                new SampleItem(true, "1"), new SampleItem(true, "2"), new SampleItem(true, "3"), new SampleItem(true, "4"),
                new SampleItem(true, "4"), new SampleItem(true, "5"), new SampleItem(true, "6"), new SampleItem(true, "7"),
                new SampleItem(true, "1"), new SampleItem(true, "2"), new SampleItem(true, "3"), new SampleItem(true, "4"),
                new SampleItem(true, "4"), new SampleItem(true, "5"), new SampleItem(true, "6"), new SampleItem(true, "7"),
                new SampleItem(true, "1"), new SampleItem(true, "2"), new SampleItem(true, "3"), new SampleItem(true, "4"),
                new SampleItem(true, "4"), new SampleItem(true, "5"), new SampleItem(true, "6"), new SampleItem(true, "7"),
                new SampleItem(true, "1"), new SampleItem(true, "2"), new SampleItem(true, "3"), new SampleItem(true, "4"),
                new SampleItem(true, "4"), new SampleItem(true, "5"), new SampleItem(true, "6"), new SampleItem(true, "7"),
                new SampleItem(true, "1"), new SampleItem(true, "2"), new SampleItem(true, "3"), new SampleItem(true, "4"),
                new SampleItem(true, "4"), new SampleItem(true, "5"), new SampleItem(true, "6"), new SampleItem(true, "7"),
                new SampleItem(true, "1"), new SampleItem(true, "2"), new SampleItem(true, "3"), new SampleItem(true, "4"),
            };
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}
0

There are 0 answers