近距离卸载儿童窗口(silverlight mvvm)

时间:2011-07-26 17:41:24

标签: silverlight mvvm-light childwindow

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

我正在从我的viewmodel打开子窗口,但是在关闭之后它仍然会触发像comboboxes上的selectionchanged这样的事件。

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

但是当它关​​闭时,我想“妥善处理”儿童窗口。

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

    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;
    }

没有成功..

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

    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;
    }

2 个答案:

答案 0 :(得分:1)

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

因此,在您看来,您必须注册Unloaded事件;然后,您可以致电Messenger.Unregiser(this);,这是您的观点。

在ViewModels中,您必须确保调用Cleanup方法以将ViewModel注销为邮件收件人。

另见:

MVVM Light Listener not releasing / deterministic finalization for registered object?MVVM Light Messenger executing multiple times

Laurent意识到这个问题但是 - 截至目前 - 没有解决方案。

答案 1 :(得分:0)

  1. 在视图之间共享ViewModel可能会导致这样的问题。这就是为什么很少这样做。
  2. ViewModel通常不应该关注导航,因为在理想的世界中,它甚至不应该知道它绑定的视图类型。这包括产生儿童视图(ChildWindows)。
  3. 我建议你做两处修改。第一个是为对话框创建专用的视图模型。第二,通过将导航委派给Controller来将导航与viewmodel分离。 MVVM中的控制器通常是一个单独的对象,其目的是打开窗口,对话框等。这可以使用Event Aggregator模式以非常优雅的方式实现。