0

如何确保我的子窗口在关闭时被卸载?

我正在从我的视图模型中打开子窗口,但是在它关闭后,它仍然会触发诸如组合框上的 selectionchanged 之类的事件。

子窗口使用与调用它的视图模型相同的视图模型,所以我想这解释了为什么事件被触发。itemssources 仍然有效。

但是当它关​​闭时,我想永远“处置”子窗口。

我试图像这样添加一个封闭的处理程序(默认视图代码后面):

    private void OnLaunchEditItem(ItemMessage msg)
    {
        var editWnd = new EditItemWindow();
        editWnd.Closed += new EventHandler(editWnd_Closed);
        editWnd.Show();
    }

    void editWnd_Closed(object sender, EventArgs e)
    {
        sender = null;
    }

没有成功。。

所以我现在正在做的是从子窗口控件中删除 itemssource,在我看来这不是解决问题的理想方法。必须有可能在关闭时将其全部从内存中处理掉?(子窗口“查看”代码隐藏)

    private void OKButton_Click(object sender, RoutedEventArgs e)
    {
        this.DialogResult = true;
        combobox1.ItemsSource = null;
        combobox2.ItemsSource = null;
    }

    private void CancelButton_Click(object sender, RoutedEventArgs e)
    {
        this.DialogResult = false;
        combobox1.ItemsSource = null;
        combobox2.ItemsSource = null;
    }
4

2 回答 2

1

消息传递有一个已知问题,即它在消息传递者和消息接收者之间引入了硬链接。因此,如果您使用消息传递,则必须确保Messenger.Unregister调用该方法。换句话说,当您打电话Register来处理消息时,请确保您也打电话Unregister

因此,在您看来,您必须注册该Unloaded活动;然后你打电话给Messenger.Unregiser(this);where 这是你的观点。

在 ViewModels 中,您必须确保Cleanup调用该方法以将 ViewModel 取消注册为消息接收者。

另见:

MVVM Light Listener 没有为注册对象释放/确定性终结?MVVM Light Messenger 执行多次

Laurent 意识到了这个问题,但是 - 到目前为止 - 没有解决方案。

于 2011-07-30T06:07:57.960 回答
0
  1. 在视图之间共享 ViewModel 可能会导致这样的问题。这就是为什么很少这样做。
  2. ViewModel 通常不应该关心导航,因为在理想世界中,它甚至不应该知道它绑定到什么样的视图。这包括生成子视图 (ChildWindows)。

我会向您推荐两个更改。第一个是为您的对话框创建一个专用的视图模型。其次,通过将导航委托给控制器来将导航与视图模型分离。MVVM 中的控制器通常是一个单例对象,其全部目的是打开窗口、对话框等。这可以使用事件聚合器模式以一种非常优雅的方式实现。

于 2011-07-26T17:47:38.517 回答