Datagrid.IsSelected绑定和滚动

本文关键字:滚动 绑定 IsSelected Datagrid | 更新日期: 2023-09-27 17:59:59

我使用MVVM,并使用一些代码将数据网格绑定到集合:

<DataGrid ItemsSource="{Binding Entites}" AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True" 
                  SelectedItem="{Binding SelectedEntity}">

我也可以使用样式(RowStyle或ItemContainerStyle)绑定到IsSelectedProperty

<DataGrid.RowStyle>
        <Style>
              <Setter Property="DataGridRow.IsSelected" Value="{Binding IsSelectedProperty, Mode=TwoWay}" />                        
        </Style>
</DataGrid.RowStyle>

它运行良好。但如果我上下滚动数据网格,它就会停止工作。

Datagrid.IsSelected绑定和滚动

我遇到了这个问题,原因是我的DataGrid正在使用虚拟化-当您将选定的DataGridRow从屏幕上滚动时,DataGridRow视觉元素要么被销毁,要么创建一个新的元素,或者-如果DataGrid的VirtualizingStackPanel.VirtualizationMode属性设置为Recycling-它将被重新用于进入视口的任何行。

当任一事件发生时,ViewModel(及其IsSelectedProperty属性集)和DataGridRow(其IsSelected属性集)之间的绑定将断开。

要确认这种情况,请尝试将DataGrid的EnableRowVirtualization属性设置为false。

在我的案例中,我需要使用虚拟化所需的性能,并最终使用Attached Behaviors实现了可选择性:具体地说,单击一行将使用LeftClickCommand附加的行为来调用ViewModel上设置IsSelectedProperty的委托命令。然后,我在DataGridRow的样式中使用绑定到IsSelectedPropertyDataTrigger来突出显示该行。

这个解决方案本质上涉及滚动您自己的选择机制,但这是我发现的同时获得行虚拟化和MVVM友好行选择的唯一方法。

尝试在DataGrid上将虚拟化模式设置为标准:VirtualizingStackPanel.VirtualizationMode="Standard"

我相信虚拟化是默认开启的,但模式是循环使用。因此,当在滚动上创建新行时,由于某些原因,IsSelected属性不会被重新评估。

在RowStyle中绑定有什么特殊原因吗?我一直将SelectedItem直接绑定到ViewModel中的SelectedEntity属性。