开发者

WPF DataTemplate performance

开发者 https://www.devze.com 2023-01-12 00:43 出处:网络
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.

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.

My problem is that our DataTemplate is sort of heavy AND the app could have around 1000 objects using that 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.

WPF DataTemplate performance

Thanks!

This is my code:

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;开发者_JS百科
        }
    }
}

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 are the way to go but you don't want all of them instansiated if only say 20 are visible on screen:

Try virtualizing stackpanel. If you don't need the list view functionality opt for ListBox. Simpler control => better performance.

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}"
     />
0

精彩评论

暂无评论...
验证码 换一张
取 消