我有WPF .Net 4项目,其中存在内存泄漏问题。经过调查我发现窗口中的问题与标签。
选项卡中的数据显示为View,有两种类型的视图(Type1View和Type2View)。将所选项从type1更改为type2(或相反)后,将调用构造函数。我认为存在问题的根源,因为之后内存消耗增加,但是在关闭选项卡后不会清除。我试图使用GC.Collect,但它没有帮助。你能告诉我,如何解决这个问题?
下面的标签窗口实现(没有标签关闭)的测试项目代码:
标签窗口的XAML:
<Window x:Class="TestApp.Views.TypesViewTabWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TypesViewTabWindow" Height="294" Width="520">
<Window.Resources>
<ResourceDictionary Source="ResourceDictionaries\TabDictionary.xaml" />
</Window.Resources>
<TabControl IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Workspaces}"
Margin="4"
HorizontalContentAlignment="Stretch"
Background="White" >
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Width" Value="{Binding ElementName=ContentSite, Path=ActualWidth}" />
<Setter Property="IsSelected" Value="{Binding IsActive}" />
<Setter Property="Template" Value="{StaticResource TabItemStyle}" />
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
</Window>
标签窗口的资源字典:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ViewModel="clr-namespace:TestApp.ViewModels" xmlns:View="clr-namespace:TestApp.Views"
xmlns:gif="http://wpfanimatedgif.codeplex.com">
<DataTemplate DataType="{x:Type ViewModel:Type1AgregateViewModel}" x:Shared="False">
<View:Type1View />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModel:Type2AgregateViewModel}" x:Shared="False">
<View:Type2View />
</DataTemplate>
<ControlTemplate x:Key="TabItemStyle" TargetType="{x:Type TabItem}">
<Grid x:Name="gr">
<Border Name="Border" Background="#F0F0F0" BorderBrush="LightGray" BorderThickness="1,1,1,0" CornerRadius="4,4,0,0" Margin="-2,0,3,0" SnapsToDevicePixels="True" >
<Grid Margin="10,0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="15" />
</Grid.ColumnDefinitions>
<TextBlock ToolTip="{Binding Path=Name}" MaxWidth="135" x:Name="TextBlock" Margin="10,5,10,5" FontSize="15" Foreground="DarkGray" Grid.Column="1"
Text="{Binding Path=Name}" HorizontalAlignment="Center" VerticalAlignment="Center" TextTrimming="WordEllipsis"/>
</Grid>
</Border>
</Grid>
</ControlTemplate>
标签窗口的ViewModel:
public class TypesViewTabViewModel : ViewModelBase
{
private readonly Dispatcher _currentDispatcher;
public TypesViewTabViewModel()
{
_currentDispatcher = Dispatcher.CurrentDispatcher;
}
/// <summary>
/// workspace for the tabs
/// </summary>
private ObservableCollection<AbstractWorkspaceViewModel> _workspaces;
/// <summary>
/// workspace for the tabs
/// </summary>
public ObservableCollection<AbstractWorkspaceViewModel> Workspaces
{
get
{
if (_workspaces == null)
{
_workspaces = new ObservableCollection<AbstractWorkspaceViewModel>();
}
return _workspaces;
}
}
public void AddNewWorkspace(AbstractWorkspaceViewModel newWorkspace)
{
if (newWorkspace == null) throw new ArgumentNullException("newWorkspace");
var viewModel = newWorkspace as IIdentifier;
try
{
AbstractWorkspaceViewModel workspace;
if (viewModel != null)
{
var taskAgregateViewModels = Workspaces.OfType<IIdentifier>().ToList();
workspace = (AbstractWorkspaceViewModel)taskAgregateViewModels.Where(t => ((t.Id == viewModel.Id) && (t.GetType() == viewModel.GetType()))).FirstOrDefault();
if (workspace == null)
{
workspace = (AbstractWorkspaceViewModel) newWorkspace.Clone();
Workspaces.Add(workspace);
}
}
else
{
workspace = (AbstractWorkspaceViewModel)newWorkspace.Clone();
var indexWorkspace = Workspaces.IndexOf(workspace);
if (indexWorkspace < 0) Workspaces.Add(workspace);
}
SetActiveWorkspace(workspace);
}
catch (Exception ex)
{
throw new Exception();
}
}
private void SetActiveWorkspace(AbstractWorkspaceViewModel workspace)
{
if (workspace == null) throw new ArgumentNullException("workspace");
var collectionView = CollectionViewSource.GetDefaultView(Workspaces);
if (collectionView == null) return;
collectionView.MoveCurrentTo(workspace);
collectionView.Refresh();
}
}
其他视图和视图模型仅包含构造函数和一些字段。完整示例项目:https://www.dropbox.com/s/y2awoul21wekphw/TestApp.zip?dl=0