我正在开发一个应用程序,我想添加一些很酷的图标。因为我正在使用漂亮的MahApps库,所以我希望在MahApps.Metro / MahApps.Metro.Resources / Icons.xaml中的图标上有一个视觉效果,所以我做了一些字符串操作来抓取每个的x:Key
部分<Canvas x:Key="appbar_3d_3ds" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
行。简而言之,我所做的所有字符串操作最终都得到了以下1216个副本:
<controls:Tile
Title="appbar_zune" Count="1215" Grid.Row="121" Grid.Column="15" TiltFactor="2" Width="1*" Height="1*" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Rectangle Margin="0" Fill="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}">
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill"
Visual="{StaticResource appbar_zune}" />
</Rectangle.OpacityMask>
</Rectangle>
</controls:Tile>
请注意,<control:Tile
的每个副本都已正确设置了Count
,Grid.Row
和Grid.Column
相应的属性。
但是,我总是以Application not responding
窗口消息结束。就像我说的那样,我的动机只是为了获得一系列漂亮图标的视觉效果,而是让我的应用程序崩溃了。我只是想知道是否有办法显示如此庞大的集合而不会崩溃任何人的计算机(注意:系统内存非常低:我在虚拟机内运行的测试机器之一)。
答案 0 :(得分:3)
首先,让你的Fill绑定具有Mode = OneWay。我打赌你不需要它是TwoWay,它可能是你的设置中的默认。 TwoWay绑定的成本要高得多。
其次,考虑使用更严酷的版本:Mode = OneTime。由于图标不太可能更改,因此您根本不需要任何更改跟踪。这将为您节省更多资源。
在你的情况下,First + Second可能不会给你带来巨大的推动力,但值得尝试和记忆。
第三,你的VisualBrush
es怎么样?他们都使用相同的Visual="{StaticResource appbar_zune}"
吗?那么为什么要创建数千个实例呢?而不是复制粘贴,只创建一个实例,并使所有项目使用该实例。你可以节省很多时间和记忆。
第四,也是最重要的,通常是给予最大的加速,是 - 你有吨的项目。我打赌你有一些滚动,水平或垂直。但是你如何生成和展示那些物品呢?一次创建它们是浪费的。它们并不适合所有屏幕,对吗?
你有一些ItemsControl产生了这千件物品吗?调查该ItemsControl的ItemsPanel
属性,并在该面板上启用virtualizing
选项。这将导致它链接到滚动条,它将动态启动仅创建屏幕上的项目并销毁在屏幕外移动的项目。好吧,我过分简化了它,但是让它说得那样。请注意,像ListBox
(以及许多其他)这样的容器也是ItemsControl,所以它也适用于此。
或许你有一个巨大的显式XAML文件,其中有一千个控件在StackPanel
内没有ItemsControl?那不是明智之举。但是哦,你仍然可以打开那个StackPanel上的virtualization
。
如果你有超过几十个项目,打开虚拟化通常是一个好主意。通常你必须有一百个,如果你达到数千甚至更多,这是必须的。但是,虚拟化成本:它经常重置/重新初始化项目。如果您的ItemTemplate非常复杂,虚拟化可能会导致滚动变得“锯齿状/滞后”,我不知道如何用英语表达,抱歉。合成器线程可能没有足够的时间来重新计算和重新传输所有快速移动的项目。如果遇到该问题,请尝试将项目的Height
设置为不变的真正固定常量值。它有助于加快布局。但如果您的ItemTemplate真的很复杂,它也可能无济于事。在这种死胡同的情况下,您唯一的选择是......重新设计并简化项目模板。
编辑:
当然,如果你没有滚动条并且你想要一次显示大量的物品,那么所有这些都不会给你带来任何好处。在这种情况下,努力简化或删除绑定,模板,组件嵌套(有时手动计算位置比使用三个嵌入网格更好),use rendering cache或(...)..对不起,我开始制作太多猜测,选择太多..
编辑:
我刚注意到Width="1*"
和Stretch
,所以你可能在顶部有一个Grid,而不是StackPanel。由于您希望它们具有相同的大小,UniformGrid
可能会有更好的性能。此外,通过一些工作,您也可以向网格添加虚拟化:
哦,关于虚拟化的最后一句话:请记住,当ScrollView在虚拟化模式下工作时,Position
不再以像素/点数计算。在v-mode中,滚动条的位置在items
中计算,也就是说,position = 2.5表示滚动条位于第三个项目的中间(2个项目通过,另外一个项目),而不是pos = 2.5“像素”。
旁注:“百万点画布”:https://blogs.msdn.microsoft.com/kaelr/2010/08/11/zoomableapplication2-a-million-items/