Fra*_*ori 42 c# silverlight mvvm silverlight-4.0 mvvm-light
我喜欢MVVM Light的Messenger及其灵活性,但是当我忘记明确取消注册收件人时(在Silverlight 4中),我遇到了内存泄漏.
原因在这里解释,但我很好,因为我认为明确取消注册收件人是一个好习惯,而不是依赖于Messenger使用弱引用.问题是说起来容易做起来难.
ViewModel很简单:您通常可以完全控制它们的生命周期,并且可以Cleanup()在不再需要它们时使用它们.
另一方面,视图更加棘手,因为它们是通过DataTemplates实例化和销毁的.对于前者 你可以把ItemsControlwith MyView和DataTemplate 想象成一个ObservableCollection<MyViewModel>.该MyView控件创建/绑定引擎收集的,你有没有什么好办法对他们手动调用清理().
我有一个解决方案,但想知道它是否是一个体面的模式或有更好的选择.我们的想法是从ViewModel发送一条特定的消息,告诉相关的View处理:
public class MyViewModel : ViewModelBase
{
...
public override void Cleanup()
{
// unregisters its own messages, so that we risk no leak
Messenger.Default.Unregister<...>(this);
// sends a message telling that this ViewModel is being cleaned
Messenger.Default.Send(new ViewModelDisposingMessage(this));
base.Cleanup();
}
}
public class MyView : UserControl, ICleanup
{
public MyView()
{
// registers to messages it actually needs
Messenger.Default.Register<...>(this, DoSomething);
// registers to the ViewModelDisposing message
Messenger.Default.Register<ViewModelDisposingMessage>(this, m =>
{
if (m.SenderViewModel == this.DataContext)
this.Cleanup();
});
}
public void Cleanup()
{
Messenger.Default.Unregister<...>(this);
Messenger.Default.Unregister<ViewModelDisposingMessage>(this);
}
}
Run Code Online (Sandbox Code Playgroud)
因此,当您在viewModel上调用Cleanup()时,所有使用它作为DataContext的视图也将执行其本地Cleanup().
你怎么看?我错过了一些明显的东西吗
ViewModelLocator类有助于为视图模型保留集中存储.您可以使用此类来帮助管理新版本并清理旧版本.我总是通过定位器从视图中引用我的viewmodel,所以我总是有可以运行的代码来管理这些东西.你可以试试.
同样,我使用Cleanup方法调用Messenger.Unregister(this),它清除来自该对象的信使的所有引用.你必须每次都调用.Cleanup(),但这就是生活:)
我没有使用过 MVVM Light(尽管我听说过很棒的事情),但如果您想要使用 WeakReferences 的 Messenger 实现,请查看此处包含的 Messenger http://mvvmfoundation.codeplex.com/。
| 归档时间: |
|
| 查看次数: |
11909 次 |
| 最近记录: |