【问题标题】:MVVM stuck event hookMVVM 卡住事件挂钩
【发布时间】:2016-02-27 04:39:21
【问题描述】:

首先我会说这是一个非常简化的示例,我的问题是在一个更大的项目中,所以虽然重组我正在做的事情是最好的方法,但它不是一个选项,我正在寻找一些东西如果可能,我可以添加到此示例以解决底部的问题。

我有 2 个viewmodelsPersonAddress)。

Person.cs

public class Person : ViewModelBase
{
}

Address.cs

public class Address : ViewModelBase
{
    public Address() : base()
    {
       Model.OnModelChanged += Model_OnModelChanged;
    }

    private void Model_OnModelChanged(object sender, EventArgs e)
    {
    }        
}

如您所见,Address on construction 正在与模型挂钩,这是重要的部分

这两个对象的视图是。

Person.xaml

<Style TargetType="{x:Type local:Person}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:Person}">
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="Person"/>
                    <local:Address/>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Address.xaml

   <Style TargetType="{x:Type local:Address}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:Address}">
                    <TextBlock Text="Address"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Person 视图自己引入了Address 视图模型,如果我将Person 的2 个实例添加到主窗口的列表中,视图将创建Address 的2 个新实例,这是由设计和伟大。

我的问题是,如果您从集合中删除 Person 的一个实例,您会留下 2 个 person 和 address 实例,一个由事件挂钩保存在内存中。

如果视图模型已通过视图引入可视化树并挂钩事件,您如何摆脱它们?

【问题讨论】:

  • 感谢您的问题不仅仅是通常的代码转储。但是你过于简单化了。请提供可靠地重现问题的a good, minimal, complete code example。另外,我真的不认为需要所有图像。我认为没有必要查看内存分析器窗口来了解您想要取消订阅某些事件处理程序。
  • 您需要跟踪集合/容器/???中的添加和删除,添加时您需要订阅该事件,删除时您需要取消订阅。或者,至少这是一个人通常会做的事情。你在做什么有点奇怪,以至于我不完全理解它。进行添加/删除的人需要控制此订阅过程。如果您以某种不允许的方式进行操作,请停止用那把锤子敲打自己的头部。重构。
  • 您的问题到底是什么?可以预料,对象将保留在内存中(假设您没有其他对它的引用),直到 GC 决定收集它。如果你想专门释放一个对象的非托管资源,你必须实现disposal模式并调用dispose方法
  • 有点忙于工作以正确更新此问题以提供更多详细信息,但是当我向其中添加一个人时,基本上有一个绑定到 Persons 集合的列表,它出现在屏幕上他们的地址,当我删除它时,人和地址都被地址中的事件挂钩卡在内存中,我希望有人有一个解决方案,我可以在不重写一个非常大的项目的情况下包含它。
  • 两个实体之间没有关系?就像PersonAddress?在这种情况下,地址视图模型应该消失了,如果你删除它所包含的人。

标签: c# wpf xaml mvvm memory-leaks


【解决方案1】:

实现 IDisposable 并删除 OnModelChanged 的​​侦听器,我不确定是否需要在两个类中实现 idisposable,以及在 person 类中调用 dispose on address。但是您肯定必须在地址 Dispose 方法中删除侦听器。

另一种选择是查看弱事件模式,但我不熟悉它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-16
    • 2016-09-22
    • 2013-04-01
    • 2015-06-05
    • 2011-05-08
    • 2013-11-01
    • 1970-01-01
    • 2011-03-01
    相关资源
    最近更新 更多