空ItemsControl导致WPF中的内存泄漏

时间:2018-09-19 12:51:59

标签: c# wpf

我在使用WPF时遇到了一个奇怪的问题。

我们正在使用带有ContentTemplateSelector的TabControl来呈现不同的页面:

<Window x:Class="LeakTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:LeakTest"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Window.Resources>
    <local:TemplateSelector x:Key="TemplateSelector"/>

    <DataTemplate x:Key="Template0">
        <Grid>
            <TextBlock>Template0</TextBlock>
            <local:DebugControl/>
            <!-- DebugControl stops leaking if ItemsControl or AlternationCount attribute is removed -->
            <ItemsControl AlternationCount="10"/>
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="Template1">
        <TextBlock>Template1</TextBlock>
    </DataTemplate>
</Window.Resources>
<TabControl ItemsSource="{Binding TabItems, Mode=OneTime}" ContentTemplateSelector="{StaticResource TemplateSelector}">            
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=Index}"/>
        </DataTemplate>
    </TabControl.ItemTemplate>
</TabControl>        

隐藏此代码:

namespace LeakTest
{
    public class TabItem {
        public int Index {
            get; private set;
        }

        public TabItem(int index)
        {
            this.Index = index;
        }
    };

    public class TemplateSelector : DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            TabItem i = (TabItem)item;

            Window win = Application.Current.MainWindow;
            return win.FindResource("Template"+i.Index) as DataTemplate;
        }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private List<TabItem> tabItems = new List<TabItem>() { new TabItem(0), new TabItem(1) };
        public IList<TabItem> TabItems => tabItems;
    }
}

DebugControl只是一个空的UserControl。如预期的那样,每次打开第一个选项卡时,都会创建一个DebugControl的新实例。但是,一旦在第一个选项卡上添加了空的ItemsControls,便永远不会释放UserControl实例: Screenshot from VS memory profiler

这是ItemsControl中的错误,还是我在做其他导致该问题的错误操作?

0 个答案:

没有答案