首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >显示UI呈现时的加载指示符

显示UI呈现时的加载指示符
EN

Stack Overflow用户
提问于 2018-01-03 08:11:49
回答 1查看 982关注 0票数 0

更新整个问题,使之更加具体

我有一个WPF应用程序,当加载时,它显示一个循环加载指示符,而另一个线程正在从服务器获取数据并操作数据。

这个WPF应用程序有一个ItemsControl,它有大约500个条目,有超过10个不同的模板。我有一个模板选择器,可以根据项目的属性确定要使用的模板。

我有一个复选框,用于显示和隐藏UI中每个项中的某些文本块。当我选中复选框时,UI将冻结10秒,然后开始使用文本块再次响应。如果我取消选中复选框,它将冻结约7秒,然后文本块将消失。

我知道我应该使用虚拟化,但它并不适用于我,因为每个项目都没有相同的高度。我试过“标准”VirtualizationMode,它只是缓慢的滚动下来,不能使用我,和“回收”将无法工作,因为项目没有相同的高度。

而不是让UI冻结7-10秒,我想显示一个加载指示符。我不是在问如何在加载应用程序时显示加载指示符,而是在UI忙于重新绘制时如何显示加载指示符。

请指教,谢谢!

EN

回答 1

Stack Overflow用户

发布于 2018-01-03 09:39:13

IIRC有一些,但请考虑一下--当UI将要呈现时,绘图区域是脏的,可以随时更新。更新即将发生。如果更新需要很长时间(比如说,3秒),那么即使您的连体/viewmodel/etc对“我开始呈现”事件有反应,您想要实际做什么呢?

显示忙指示器?显示?这是个变化。它会标记相关区域脏,但是一些东西已经脏了,重画还在等待,而且需要很长时间(3s),对吗?因此,如果您显示/隐藏任何内容,它将在呈现完成后显示。也就是说,你的忙碌指示器可能会出现在3s之后,并会立即隐藏。

当然,这与其他事情无关。当呈现开始时,您可以发送TCP数据包、播放声音、显示另一个窗口/表面以及它自己的独立的三个(这样它们就不会等到第一次呈现完成)等等。

我认为你真正需要做的是:

  • 优化创建和数据绑定
    • 不要在UserControls构造函数中加载数据
    • 使所有数据绑定属性尽可能快地读取,在getter中没有数据库/网络访问,等等;返回NULL,触发后台任务,更新属性,并在数据可用时引发更改。
    • 尽可能使用OneWay甚至OneTime绑定
    • 不要过度使用UI回调,比如事件、转换器、模板选择器;如果真的需要它们,请让它们快速运行。
    • (...)

  • 努力限制UI元素的更改数量
    • 也许你不需要所有的?
    • 也许您可以合并其中的一些,以获得相同的效果与更少的UI对象?
    • 也许您可以缓存一些现成的元素,这样就不需要创建它们了?
    • 也许你能把他们的影像藏起来?意思是,渲染-位图缓存,所以WPF甚至不需要渲染它们,只需告诉GPU使用缓冲图像?
    • 如果在virtualization可滚动区域中显示了大量新的UI元素,您可以在UI或/和数据元素上使用只显示那些现在确实可见的内容,并修剪掉所有在视图端口之外的元素(WPF对此有一些很好的支持)
    • 也许你可以一次显示UI元素的数量?与其显示一个繁忙的指示符和无数个新元素,并让它们在3s后全部显示出来,不如显示繁忙的指示符和前100个元素,等待一段时间(或直到呈现),然后再开始泵出更多要显示的元素(同样,并不是一次全部显示,因为可能忙碌的指示器会被动画化,并且会冻结.)?
    • (...)

  • 努力简化要显示的无数元素的UI模板,因此它们很快就会显示
    • 限制它们的深度(例如,将usercontrol>grid>scroll>listbox>panel>[items:usercontrol>grid>listbox>panel>[items:grid>textblock]的布局更改为usercontrol>grid>listbox>scrollpanel>[items:textblock]]
    • 限制UI元素的更改数量
    • 限制布局计算的数量(如果不需要,不要更改大小,对尺寸、边距等使用常量值,而不是在可能的情况下计算)
    • 如果可能的话,使用renderTransforms而不是layoutTransforms
    • 对于复杂的背景使用复杂的刷子(甚至是VisualBrushes),而不是将它们作为布局元素构建在画布上。
    • 在这些亿万项中,尽可能限制绑定和增加资源使用(意思是,在XAML等中的{StaticResource} )。如果您显示不同颜色的10k元素,有时最好定义50个通过StaticResources设置颜色的项模板(so,redItemTemplate,greenItemTemplate,blueItemTemplate,.)而不是有一个commonItemTemplate将它的所有颜色绑定在itemViewModel上
    • (...)

以此类推,这是初学者的基础。除了一些基本点外,WPF的优化实际上可能是很困难的。我从以前的经验中了解到的大多数文章,都帮助我成功地优化了许多应用程序:

现在,回答你的问题,尽管我仍然认为这不是正确的方法:

  • 在呈现启动时检测:只需使用event CompositionTarget.RenderMSDN
  • 呈现结束时的检测:在计划呈现之后,在调度器上发送一个具有优先级的DispatcherPriority.ContextIdleMSDN来源文章任务。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48073515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档