WPF:ObservableCollection内存泄漏

时间:2016-05-13 09:13:17

标签: c# wpf xaml mvvm memory-leaks

[我很抱歉我的英语不好]

在我的MainWindow我有一些ContentControl,我将Content设置为一个名为SimpleView的视图。如果SimpleView ListBox绑定到收藏集,即使我删除SimpleView,该视图仍然有效。

我的所有视图模型都是实现INotifyPropertyChanged。 这是我的代码:

MainWindow.xaml

<Window x:Class="WpfMemory.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <Button Content="Set view" Click="SetView" />
            <Button Content="Clear view" Click="ClearView" />
        </StackPanel>

        <ContentControl x:Name="ViewContainer" Grid.Row="1" Margin="4" />
    </Grid>
</Window>

代码

private void SetView(object sender, RoutedEventArgs e)
{
    var simpleViewModel = new ViewModels.SimpleViewModel();
    var simpleview = new Views.SimpleView() { DataContext = simpleViewModel };
    ViewContainer.Content = simpleview;
}

private void ClearView(object sender, RoutedEventArgs e)
{
    ViewContainer.Content = null;
    System.GC.Collect();
}

SampleView.xaml

<UserControl x:Class="WpfMemory.Views.SimpleView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition MinWidth="60"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition />
        </Grid.RowDefinitions>

        <TextBlock Text="SomeText" />
        <TextBox Text="{Binding SomeText}" Grid.Column="1"/>

        <TextBlock Text="Large data" Grid.Row="1"/>
        <ListBox ItemsSource="{Binding LargeData,Mode=OneTime}" 
                 Grid.Row="2" Grid.Column="1" 
                 DisplayMemberPath="Name" />

    </Grid>
</UserControl>

查看模型

public sealed class SimpleViewModel : ViewModelBase
{
    public SimpleViewModel()
    {
        var items = Enumerable.Range(1, 10000)
            .Select(x => new SimpleItem()
            {
                Id = x,
                Name = "Item " + x
            })
            .ToArray();

        LargeData = new ObservableCollection<SimpleItem>(items);
    }

    public string SomeText{ get; set; } = "yehudah";

    ObservableCollection<SimpleItem> largeData;
    public ObservableCollection<SimpleItem> LargeData
    {
        get { return largeData; }
        set { SetProperty(ref largeData, value); }
    }
}

public sealed class SimpleItem : ViewModelBase
{
    public int Id { get; set; }
    public string Name { get; set; }
}

我运行应用程序并单击SetView,然后单击ClearView。 现在,在vs诊断工具中,我点击“拍摄快照”这就是结果:

Memory snapshot

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我认为你应该在卸载内容控件时重置 simpleview.DataContext

你可以做到

{{1}}

SetView 时。