WPF DataTemplate性能 [英] WPF DataTemplate performance
问题描述
这里的问题是,如果您为一个对象类型拥有一个DataTemplate,则每次存在该对象时,都会创建一个DataTemplate,听起来很正确.
Well the problem here is that if you have one DataTemplate for a type of object, each time the object is present, the DataTemplate will be created, that sounds about right.
我的问题是我们的DataTemplate太重了,使用该DataTemplate的应用可能有大约1000个对象.
My problem is that our DataTemplate is sort of heavy AND the app could have around 1000 objects using that DataTemplate.
我创建了一个简单的示例,其中创建了5个Person对象,并将它们绑定到ListView. Person对象的DataTemplate是带有标签的Grid和带有2个MenuItems的ContextMenu.为了简单起见,我只想专注于MenuItems.使用内存分析器,我可以看到总共有10个MenuItem对象(每人2个,5人* 2 MenuItem = 10 MenuItem),我想知道是否有避免这种情况的方法.说,每个Person对象应该共享相同的MenuItem引用,以避免每次创建一个人时都重复DataTemplate.
I created a simplistic example where I created 5 Person objects and I bind them to a ListView. The DataTemplate for the Person object is a Grid with a Label and a ContextMenu with 2 MenuItems. For simplicity I just want to concentrate in the MenuItems. Using a memory profiler, I can see that there are a total of 10 MenuItem objects (2 per Person, 5 Person * 2 MenuItem = 10 MenuItem), and I want to know if there is a way to avoid this. Say, every Person object should share the same MenuItem reference, to avoid duplicating the DataTemplate each time a person is created.
这些是内存分析器中的结果.
These are the results in the memory profiler.
谢谢!
这是我的代码:
C#
using System.Collections.Generic;
using System.Windows;
namespace MenuItemsTest
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
this.DataContext = new List<Person>()
{
new Person("Jim Morrison"),
new Person("Jimmy Page"),
new Person("Jimmy Hendrix"),
new Person("Janis Joplin"),
new Person("Peter Frampton")
};
}
}
public class Person
{
public string Name { get; set; }
public Person(string name)
{
this.Name = name;
}
}
}
XAML:
<Window x:Class="MenuItemsTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MenuItemsTest"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<DataTemplate DataType="{x:Type local:Person}">
<Grid>
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Header="Select" />
<MenuItem Header="Deselect" />
</ContextMenu>
</Grid.ContextMenu>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Name}" />
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<ListView ItemsSource="{Binding}" />
</Grid>
</Window>
推荐答案
使用DataTemplates是可行的方法,但是如果只说20个在屏幕上可见,您不希望所有实例都被实例化:
DataTemplates are the way to go but you don't want all of them instansiated if only say 20 are visible on screen:
尝试虚拟化Stackpanel.如果不需要列表视图功能,请选择ListBox.控制更简单=>更好的性能.
Try virtualizing stackpanel. If you don't need the list view functionality opt for ListBox. Simpler control => better performance.
非常重要的一点是,不要让ListView维度不受限制(即,不要在其周围设置滚动查看器),因为即使使用虚拟化堆栈面板,这也会实例化所有数据模板.
It's very important that you don't let ListView dimension get unbounded (ie don't set a scrollviewer around it) as that will instansiate all data templates even if you use virtualizing stackpanel.
<ListView
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Standard"
ItemsSource="{Binding}"
/>
这篇关于WPF DataTemplate性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!