我在使用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实例:
这是ItemsControl中的错误,还是我在做其他导致该问题的错误操作?