【问题标题】:UserControl created with DataTemplate has dispose issue使用 DataTemplate 创建的 UserControl 存在处理问题
【发布时间】:2013-10-31 13:01:08
【问题描述】:

我有 4 种不同的视图和不同的操作。我正在使用 DateTemplate 创建视图

<DateTemplate DateType={X:Type HomeViewModel}" >
     <HomeView>
</DateTemplate>
<DateTemplate DateType={X:Type DeviceDateViewModel}" >
     <DeviceDateView>
</DateTemplate>

我有 ContentControl,所有 ViewModel 都绑定到 Content 属性,比如“ActiveView”

我已经创建了所有 ViewModel 并保存在字典中。当我想更改视图时,我只需将 ActiveView 分配给我要显示的新视图。

void ActiveteView(ViewType viewType)
{
    ActiveView = GetViewFromDictionary(viewType);
}

我们的一个控件不支持DataBinding,所以我在View的后台代码中新建了一些控件。

我的问题是:当我更改 ActiveView 时,它会在 ContentControl 中创建新的视图和显示。因此,我遇到了问题。我的旧视图仍在记忆中。如何销毁它们?

目前,我们无法更改设计。我们可以忍受它。

【问题讨论】:

    标签: c# wpf datatemplate


    【解决方案1】:

    如果 vm 在字典中,那么垃圾收集将不会收集它。关于 GC 何时收集对象有很多规则,我自己有时必须在这个话题上刷新自己。 All about Garbage collection

    有一些方法可以强制进行垃圾收集,但恕我直言,这消除了使用 managed code 的好处。一般来说,只要您不持有对该对象的引用,GC 最终应该会收集它。您可以强制进行此类收集,但这表明您的设计有问题。

    根据 MSDN:

    “可以通过调用 Collect 来强制进行垃圾回收,但大多数情况下应该避免这样做,因为它可能会产生性能问题。”

    【讨论】:

    • 我没有处理虚拟机,当应用程序处于活动状态时我不需要这样做。我的问题是,当我更改 ActiveView 时,WPF DateTemplate(我相信 IOC 会在后面这样做)创建新视图并尝试销毁旧视图。这里我们有 3'r 部分控制的参考。这样视图就不会被破坏。
    • 如何试图摧毁旧的?它是调用 IDisposable.Dispose 还是 ~finalizer?也许将代码放入其中任何一个中以取消引用零件控制都可以。这似乎不是使用 ~finalizer 的好理由,但正如您所说,您不能更改设计。
    • 好吧,我没有 IDispose。即使我添加了 IDisposable 接口,我也不会得到任何好处。我无权访问 View。事实上,我无法访问 View 对象。 ~finalizer 也没有命中。
    • 嗯,有道理。终结器不会运行,因为它没有被垃圾回收。
    • 所以你基本上有一个对象列表。您可以控制的列表,但列表中的对象不受限制。有些东西不断创建新对象并将它们添加到列表中。这是正确的吗?
    猜你喜欢
    • 1970-01-01
    • 2013-05-16
    • 2012-11-17
    • 2012-09-15
    • 2014-08-03
    • 1970-01-01
    • 1970-01-01
    • 2017-02-18
    相关资源
    最近更新 更多