如何检测 ListView 或任何控件何时完成渲染?

Posted

技术标签:

【中文标题】如何检测 ListView 或任何控件何时完成渲染?【英文标题】:How to detect when a ListView or any control is finished rendering? 【发布时间】:2021-11-26 04:58:42 【问题描述】:

我正在使用 UWP 和 WASM 进行 Uno 项目。该项目包含一个 ListView 或 GridView,其源是 ObservableCollection。因为它是从 API 获取数据。我正在显示一个进度指示器,我发现进度指示器一直保持活动状态,直到 ObservableCollection 填充了数据项。

问题是在 ObservableCollection 拥有数据和控件完成呈现视图之间存在延迟。在这种情况下,它是图像的 ObservableCollection,不会填充 GridView 或 ListView。

我无法识别和告诉我何时停用进度指示器的事件。

【问题讨论】:

progressBar1.IsIndeterminate = false;怎么样?? 【参考方案1】:

WinUI API 中没有定义事件来告诉您 UI 何时完成渲染,因此您必须创建自己的事件。当您有一个复杂、繁重的 UI 并且在获取数据后呈现明显的延迟时,这可能是值得的。

有几种可能的策略:

在固定延迟后隐藏进度指示器。 使用CoreDispatcher.RunIdleAsync() 安排回调。这只应在 UI 线程不“忙”时引发,这是完成渲染的粗略代理。例如:Dispatcher.RunIdleAsync(_ => progressRing.IsActive = false); 特定于ListView/ItemsControl:您可以使用ContainerFromIndex() 方法检查列表是否确实具有项目视图,例如listView.ContainerFromIndex(expectedIndex) != null。请小心,因为该列表只会为实际可见的项目创建容器。 特定于Image:来自远程 url 的图像被异步加载。您可以订阅ImageOpened event 以在图像准备好时获得回调。

您可能需要进行试验以找到最适合您的场景的方法;这不是一门精确的科学。如果可能,最好在具有一系列性能的多台设备上进行测试。

【讨论】:

我想对此进行跟进。 CoreDispatcher 解决方案似乎不起作用。它会返回 false 并且在显示图像之前仍然会有很大的延迟。无论我设置什么索引,ContainerFromIndex() 都会做同样的事情。我要补充一点,进度指示器也是有问题的,因为它实际上在渲染过程中冻结了,所以看起来应用程序冻结了。我不敢相信我是唯一一个在 wasm 平台构建上看到这个的人。 确实图像的处理方式与其他控件有所不同,我添加了一些具体信息。对于进度指示器冻结,这是当前在 UI 线程上运行的 WASM 上的动画的限制。可能有其他方法,但我建议专门提出一个新问题。

以上是关于如何检测 ListView 或任何控件何时完成渲染?的主要内容,如果未能解决你的问题,请参考以下文章

检测何时在 ListView 中滑动项目

Android Webview:检测渲染何时完成

检测ListView何时到达底部 - onScroll()或onScrollStateChanged()?

检测控件的“类”属性何时更改的任何事件

DataGridView如何通过按下escape来检测用户何时从编辑控件中出来?

如何检测 iPhone MPMoviePlayer 控件何时出现/消失?