C# 如何在WPF中绘制1216个画布元素而不挂起应用程序
我正在开发一个应用程序,我想添加一些很酷的图标。因为我使用的是漂亮的MahApps库,所以我想看到MahApps.Metro/MahApps.Metro.Resources/icons.xaml中的图标,所以我做了一些字符串操作来抓取每行的C# 如何在WPF中绘制1216个画布元素而不挂起应用程序,c#,wpf,mahapps.metro,C#,Wpf,Mahapps.metro,我正在开发一个应用程序,我想添加一些很酷的图标。因为我使用的是漂亮的MahApps库,所以我想看到MahApps.Metro/MahApps.Metro.Resources/icons.xaml中的图标,所以我做了一些字符串操作来抓取每行的x:Key部分。简言之,我所做的所有字符串操作都得到了以下1216个副本: <controls:Tile Title="appbar_zune" Count="1215" Grid.Row="121" Grid.Column="15" TiltFacto
x:Key
部分。简言之,我所做的所有字符串操作都得到了以下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>
请注意,
的每个副本首先使填充绑定具有Mode=one-way。我打赌你不需要它是双向的,它可能是你设置中的缺陷。双向绑定的成本要高得多
第二,考虑使用更苛刻的版本:MODE =一次。由于图标不太可能更改,因此根本不需要任何更改跟踪。这将为您节省更多的资源
在您的情况下,第一+第二可能不会给您带来巨大的提升,但值得尝试和记住
第三,你的VisualBrush
es怎么样?它们是否都使用相同的Visual=“{StaticResource appbar_zune}”
?那么为什么要创建数千个实例呢?不要复制粘贴,只创建一个实例,并使所有项目都使用该实例。你可以节省很多时间和内存
第四,也是最重要的,通常能提供最大的加速,是-你有吨的物品。我打赌你有一些滚动,水平或垂直。但是如何生成和显示这些项目呢?一次创建它们是。。浪费的他们不适合所有的屏幕,对吗
你有一些ItemsControl可以生成那一千个项目吗?调查该项控件的ItemsPanel
属性,并打开该面板上的虚拟化
选项。这将导致它链接到滚动条,它将开始动态创建屏幕上的项目,并销毁屏幕外的项目。好吧,我把它简化了,但Letsay是这样工作的。请注意,类似于ListBox
(以及其他许多容器)的容器也是ItemsControl,因此它也适用于此处
或者,您可能有一个巨大的显式XAML文件,在一些StackPanel
中有上千个控件,而没有ItemsControl?那真的不明智。但是哦,好吧。。您仍然可以在该面板上启用虚拟化
如果您有几十个以上的项目,那么启用虚拟化通常是一个好主意。通常情况下,你必须有一百个,如果你有几千个或更多,这是必须的。但是,虚拟化成本:它通常会重置/重新初始化项目。如果您的ItemTemplate非常复杂,虚拟化可能会导致滚动变成“jaggy/laggy”,我不知道如何用英语表达,抱歉。合成器线程可能根本没有足够的时间重新计算和重新显示所有快速移动的项。如果遇到此问题,请尝试将项目的高度设置为不变的真正固定常量值。这对加快布局有很大帮助。但是,如果您的ItemTemplate非常复杂,那么它也可能没有帮助。在这种死路一条的情况下,你唯一的选择是。。。重新设计并简化项目模板
编辑:
当然,如果你没有滚动条,如果你试图一次显示大量的项目,所有这些都不会给你带来任何好处。在这种情况下,尽量简化或删除绑定、模板、组件嵌套(有时手动计算位置比使用三个嵌入网格更好),或者(…)。。对不起,我开始做太多的猜测,太多的选择
编辑:
我刚刚注意到Width=“1*”
和Stretch
,因此您可能在顶部有一个网格,而不是StackPanel。由于希望它们的大小相同,因此UniformGrid
可能具有更好的性能。此外,通过一些工作,您还可以将虚拟化添加到网格:
- 从4.5到更高,更容易-
- 下面,它需要更多的工作,请参见Dan Crevier的4部分系列博客:
- 一:
- 二:
- 三:
- 四:
如果虚拟化网格还不够,请尝试移动到画布,并手动强制某些宽度/高度/位置。删除自动布局有时会节省很多。然后,你可以使用,如果你真的把恒定大小的项目,你可能会得到它尽可能快。但这是最后的选择。前面提到的事情应该很有效
哦,关于虚拟化还有最后一句话:记住,当ScrollView在虚拟化模式下工作时,位置
不再以像素/点计算。在v模式下,滚动条的位置按项目计算,即,位置=2.5表示滚动条处于第三个项目的中间位置(2个项目通过一半以上),而不是位置=2.5“像素”
旁注:“百万点画布”:不,Visual=“{StaticResource}
是为每个图标键生成的,因此appbar_zune
只是这些键中的一个。请注意,它们是我问题中的整个代码摘录(整个
标记)通过读取c:\\Users\\myAccount\\MahApps.Metro/MahApps.Metro.Resources/Icons.xaml
文件并使用x:Key
定义生成1216个此类
标记变体(逻辑处理边距,网格.Column
和网格.Row
)所以没有绑定
在进行。那么你是说我可以使用绑定
来生成UIElements
?@emmanuel:不是直接通过绑定
,而是间接地是。这就是像ContentPresenter
或ItemsControl>这样的组件。如果你有一个列表
,而T是一个ps有关图标的所有信息,然后您可以使用
,itemscontrol将生成一个与源列表1对1同步的项目列表