Datagrid.IsSelected绑定和滚动

vit*_*dev 13 c# wpf datagrid mvvm selected

我使用MVVM,并使用一些代码将datagrid绑定到集合:

<DataGrid ItemsSource="{Binding Entites}" AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True" 
                  SelectedItem="{Binding SelectedEntity}">
Run Code Online (Sandbox Code Playgroud)

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

<DataGrid.RowStyle>
        <Style>
              <Setter Property="DataGridRow.IsSelected" Value="{Binding IsSelectedProperty, Mode=TwoWay}" />                        
        </Style>
</DataGrid.RowStyle>
Run Code Online (Sandbox Code Playgroud)

它运作良好.但是如果我向下和向上滚动数据网格,它就会停止工作.

Dan*_*n J 17

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

当任一事件发生时,ViewModel(及其IsSelectedProperty属性集)与DataGridRow(及其IsSelected属性集)之间的绑定将被破坏.

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

就我而言,我需要使用虚拟化所需的性能,并最终使用附加行为实现可选:具体而言,单击行将使用LeftClickCommand附加行为来调用设置的ViewModel上的委托命令IsSelectedProperty.然后我在DataGridRow的样式中使用了一个DataTrigger绑定IsSelectedProperty来突出显示该行.

这个解决方案主要涉及滚动自己的选择机制,但这是我发现获得行虚拟化和MVVM友好行选择的唯一方法.

  • 很好的答案.但这不是一个错误吗?如果列表框项不在屏幕上,并且我以编程方式将绑定的VM对象上的IsSelected信息设置为true,则向下滚动会显示该项已被选中.但是,如果我以编程方式将VM对象的IsSelected设置为false,则向下滚动会将列表框项显示为仍处于选中状态,并将VM的IsSelected更改回true.为什么?使用虚拟化,不应该新创建或回收的列表框项目意识到它不知道绑定对象的当前状态是什么,并从对象获取它的IsSelected值?好像是一个bug. (3认同)

Kri*_*rip 9

尝试在DataGrid上将virtualizationmode设置为标准:VirtualizingStackPanel.VirtualizationMode="Standard".

我相信默认情况下虚拟化是打开的,但模式是回收.因此,当在滚动上创建新行时,由于某种原因,IsSelected属性不会被重新评估.


Sco*_*lvi 1

您在 RowStyle 中进行绑定是否有特殊原因?我总是将 SelectedItem 直接绑定到 ViewModel 中的 SelectedEntity 属性。