【问题标题】:How to dispose of usercontrols created by DataTemplate如何处理由 DataTemplate 创建的用户控件
【发布时间】:2012-07-18 20:21:00
【问题描述】:

我必须在 WPF 中的两个视图之间切换。我有一个 DataTemplate,它使用 ViewModels 来根据 ViewModel 推断要绘制的视图。简而言之:

<DataTemplate DataType="{x:Type ..:RedScreenViewModel}">
<...:RedScreenViewModel/>
</DataTemplate>

一时兴起,我决定在视图之间快速切换.. WPF 应用程序的内存使用量飙升至 2gb。现在你可能会争辩说,在现实生活中,没有人会做我所做的事情。但我想知道如何释放分配的内存。肯定会调用 Unload,我已取消订阅任何事件处理程序。 但这无济于事。 DevExpress 或 WPF 是否具有可以告诉 .NET 处理用户控件的属性? 我为 DevExpress 找到但做 zilch 的是:

DisposeOnWindowClosing
DestroyOnClosingChildren

创建的视图非常复杂,我重新组织了布局以节省内存。但同样增加。 建议将非常感谢。

编辑: 但是没有调用析构函数...

【问题讨论】:

  • WPF 组件没有 Dispose() 方法,因为它们依赖于垃圾收集器。如果切换视图导致那么多“浪费数据”,请尝试致电GC.Collect()。此外,请确保确实不存在对旧数据的引用。
  • 没有看到你的视图/视图模型的实现,很难说为什么有这么多的内存存在。我建议使用内存分析器来找出根对象。 .NET Memory Profiler 非常棒 (memprofiler.com),而且他们有免费的线索。
  • @RafaelGoodman 我发现了问题但无法解决:(我正在使用的第三方库,它的 ItemsSource 绑定到 ObservableCollection。在幕后它订阅了该集合的 INotifiedPropertyChanged。该订阅意味着永远不会调用 Dispose。我尝试的一种方法是将我绑定的 Collection 设置为 null。这解决了问题,但我讨厌该解决方案,因为它无法正常工作。

标签: wpf devexpress datatemplate


【解决方案1】:

这就是你如何处理嵌套在 ItemsControl(在本例中为 ListBox)内的 UserControls

        public void Dispose()
        {
            if (this.listb != null)
            {
                for (int count = 0; count < this.listb.Items.Count; count++)
                {
                    DependencyObject container = this.listb.ItemContainerGenerator.ContainerFromIndex(count);
                    UserControl userControl = container.GetVisualDescendent<UserControl>();
                    IDisposable controlToPotentiallyDispose = userControl as IDisposable;
                    if (controlToPotentiallyDispose != null)
                        controlToPotentiallyDispose.Dispose();
                    controlToPotentiallyDispose = null;
                }
            }
            if (this.ViewModel != null)
            {
                this.ViewModel.Dispose();
                this.ViewModel = null;
            }
            this.listb = null;
        }

请注意,listb 是要从中查找项目的列表框的 x:Name。
此外,这个 Dispose() 方法应该在 xaml.cs 中,并且应该在您不再需要视图时调用。

HTH,

巴布。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2010-11-09
    • 1970-01-01
    相关资源
    最近更新 更多