Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF数据模板性能_Wpf_Binding - Fatal编程技术网

WPF数据模板性能

WPF数据模板性能,wpf,binding,Wpf,Binding,这里的问题是,如果一种对象有一个DataTemplate,那么每次对象出现时,都会创建DataTemplate,这听起来是对的 我的问题是我们的DataTemplate有点重,应用程序可能有大约1000个使用该DataTemplate的对象 我创建了一个简单的示例,其中我创建了5个Person对象,并将它们绑定到一个ListView。Person对象的DataTemplate是一个带有标签的网格和一个带有2个MenuItems的ContextMenu。为了简单起见,我只想专注于菜单项。使用内存分

这里的问题是,如果一种对象有一个DataTemplate,那么每次对象出现时,都会创建DataTemplate,这听起来是对的

我的问题是我们的DataTemplate有点重,应用程序可能有大约1000个使用该DataTemplate的对象

我创建了一个简单的示例,其中我创建了5个Person对象,并将它们绑定到一个ListView。Person对象的DataTemplate是一个带有标签的网格和一个带有2个MenuItems的ContextMenu。为了简单起见,我只想专注于菜单项。使用内存分析器,我可以看到总共有10个MenuItem对象(每人2个,5个人*2个MenuItem=10个MenuItem),我想知道是否有办法避免这种情况。也就是说,每个Person对象都应该共享相同的MenuItem引用,以避免每次创建Person时重复DataTemplate

这些是内存探查器中的结果

谢谢

这是我的代码:

C#

使用System.Collections.Generic;
使用System.Windows;
命名空间MenuItemsTest
{
/// 
///Window1.xaml的交互逻辑
/// 
公共部分类Window1:Window
{
公共窗口1()
{
初始化组件();
this.DataContext=新列表()
{
新人(“吉姆·莫里森”),
新人(“吉米·佩奇”),
新人(“吉米·亨德里克斯”),
新人(“Janis Joplin”),
新人(“彼得·弗兰普顿”)
};
}
}
公共阶层人士
{
公共字符串名称{get;set;}
公众人物(字符串名称)
{
this.Name=Name;
}
}
}
XAML:


数据模板是一个不错的选择,但如果屏幕上只显示20个,则不希望所有模板都实例化:

尝试虚拟化stackpanel。如果不需要列表视图功能,请选择ListBox。更简单的控制=>更好的性能

非常重要的是,不要让ListView维度变得无界(即不要在其周围设置scrollviewer),因为这将实例化所有数据模板,即使您使用虚拟化stackpanel

  <ListView 
     ScrollViewer.HorizontalScrollBarVisibility="Disabled"
     ScrollViewer.VerticalScrollBarVisibility="Auto"
     VirtualizingStackPanel.IsVirtualizing="True"
     VirtualizingStackPanel.VirtualizationMode="Standard" 
     ItemsSource="{Binding}"
     />

使用虚拟化stackpanel,我用一个相当复杂的数据模板绑定了数十亿行(我当时正在玩MemoryMappedFile)。
<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>
  <ListView 
     ScrollViewer.HorizontalScrollBarVisibility="Disabled"
     ScrollViewer.VerticalScrollBarVisibility="Auto"
     VirtualizingStackPanel.IsVirtualizing="True"
     VirtualizingStackPanel.VirtualizationMode="Standard" 
     ItemsSource="{Binding}"
     />