【问题标题】:WPF - VirtualizingStackPanel requests all items when going into editing mode in DataGridWPF - VirtualizingStackPanel 在 DataGrid 中进入编辑模式时请求所有项目
【发布时间】:2016-02-28 20:45:32
【问题描述】:

我正在使用DataGridCellEditingTemplatesItemsSource 使用了数据虚拟化集合(AlphaChiTech 解决方案),它一次只能按需获取大小为 100 项的页面。

直到一个单元格被双击进入编辑表单,然后VirtualizingStackPanel 一个接一个地请求所有项目,它才能正常工作。当然,作为副作用,所有页面最终都会被请求。

有没有办法解决这个问题?

编辑:

我找到了一种解决方法,它可能对处于我这种情况的人有所帮助:

最终我观察到,在切换到编辑表单后行高保持不变的情况下,VirtualizingStackPanel 并没有请求所有项目。在解决方法之前,我的编辑表单略高。

现在我设置了单元格(正常和编辑)中控件的 MinHeight,这样在切换到编辑表单时高度不会改变。

不幸的是,这仅在某些条件下有效。在某些情况下它不起作用:

  • 使用RowDetailsTemplate。一旦可见,虚拟化就被破坏了。我假设行详细信息属于行自身,因此行高再次增加。

  • 分别在 CollectionView 上引发 Collection 的 Reset 事件。以我的经验,这通常是使用DataGrids 进行数据虚拟化的杀手。

  • 降低集合的Count(这也不会导致重置事件成为问题)。

有趣的是,增加集合的Count 确实有效。但是我必须增强 AlphaChiTech 的功能(幸运的是,源代码在 github 上),因为没有开箱即用的 Reset 事件就无法更改Count(至少我没有找到) .此外,DataGrid's 项目必须在之后立即刷新,否则会引发异常,指出 ItemsControl 和集合确实具有不一致的状态。

行详细信息对我来说是可选的,但在不破坏数据虚拟化的情况下删除项目至关重要。因此,问题仍然存在。我的解决方法很可能会帮助拥有固定大小集合的人,但不幸的是不是我自己。

【问题讨论】:

    标签: c# wpf datagrid virtualizingstackpanel data-virtualization


    【解决方案1】:

    解决方法

    我自己找到了解决这个问题的方法。 此解决方法适用于在 WPF 中使用数据虚拟化的可编辑集合(数据虚拟化只读集合无需解决方法即可实现)。

    首先,行必须是统一大小的。我的问题之一是CellEditingTemplates 高于CellTemplates。所以每次触发编辑表单时,DataGrid 都会获取集合的所有项目。将CellTemplatesMinHeight 设置为与CellEditingTemplates 的高度匹配就可以了。

    显然,RowDetailsTemplate 属于该行,因此当使其可见时,它会更改行的高度,从而破坏数据虚拟化。因此,最好不要使用行详细信息并使用主从模式,其中“详细信息”显示在 DataGrid 之外。后者我现在正在尝试实施(未完全实施的第一次尝试效果很好,足以说明这不会造成任何麻烦)。我确实想到了行详细信息的一个例外:如果行详细信息始终可见并且每个项目具有相同大小的行详细信息,那么它可能会起作用。想法是行的高度是统一大小的,但在我的应用程序中,整个集合中只有少数项目需要详细信息,我没有尝试这种方法。

    其次,减少计数 - 意味着删除项目 - 并重置集合上的项目或DataGrid 也触发了所有项目的获取。此处的解决方法是在添加或删除项目时用相同项目的新集合对象替换现有集合。幸运的是,这个新集合也是数据虚拟化的。所以它仍然是省时的,流畅的,用户不会注意到它。但是如果在DataGrid 中选择一个项目时执行这样的“刷新”仍然存在问题。这是一个令人讨厌的解决方法:我在管理虚拟化集合的ViewModel 中实现了两个事件。它们是PreVirtualizedRefreshPostVirtualizedRefreshViewDataGrid 订阅它们并取消选择PreVirtualizedRefreshPostVirtualizedRefresh 上的DataGrid 中的每个项目,可能会再次选择取消选择的项目索引(如果已记住)。后来一个对我来说仍然不好用。

    重要的是,有了这些变通方法(使用备用主从模式并使用新集合对象刷新和取消选择项),数据虚拟化不会被破坏。

    备注

    在处理这些问题时我尝试过的所有虚拟化解决方案中,我认为 AlphaChi 解决方案是最好的。

    WPF 在构建时绝对没有考虑到数据虚拟化。另一方面,它的继任者 UWP 甚至拥有自己的数据虚拟化接口。因为我没有任何 UWP 项目,所以我无法亲自尝试,但我想这会很有趣。话虽如此,UWP 没有原生的DataGrid,因此数据虚拟化集合必须提供给Lists 或第三方DataGrids。所以也需要权衡。

    【讨论】:

      猜你喜欢
      • 2021-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-08
      • 2011-09-14
      • 2011-10-19
      • 2021-11-25
      • 1970-01-01
      相关资源
      最近更新 更多