我的wpf应用程序具有弹出的子窗口以向用户显示视图。通过在窗口的viewmodel上执行CloseCommand
来关闭子窗口,该视图模型使用自身作为令牌发送CloseWindowMessage
。
这是使用的viewmodel:
public class ChildWindowViewModel : ViewModel
{
ICommand _closeCommand;
public ICommand CloseCommand
{
get
{
if (_closeCommand == null)
_closeCommand = new RelayCommand(DoClose);
return _closeCommand;
}
}
public void DoClose()
{
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
Messenger.Default.Send(new CloseWindowMessage(),this);
}
}
这是显示窗口的方法:
protected void ShowWpfWindow(Window wpfWindow)
{
var dc = wpfWindow.DataContext as ChildWindowViewModel;
if (dc == null)
throw new ArgumentOutOfRangeException();
Action<CloseWindowMessage> action = (x) =>
{
wpfWindow.Close();
};
Messenger.Default.Register(wpfWindow, dc, action);
wpfWindow.Owner = MainWindow.Single;
wpfWindow.ShowInTaskbar = false;
wpfWindow.Show();
}
我已将调用添加到GC.Collect()
和GC.WaitForPendingFinalizers()
以进行调试。这些似乎导致变量Action<CloseWindowMessage> action
被垃圾收集。
如果我在包含的类上创建Action<CloseWindowMessage> action
字段:
Action<CloseWindowMessage> action;
protected void ShowWpfWindow(Window wpfWindow)
{
var dc = wpfWindow.DataContext as ChildWindowViewModel;
if (dc == null)
throw new ArgumentOutOfRangeException();
action = (x) =>
{
wpfWindow.Close();
};
Messenger.Default.Register(wpfWindow, dc, action);
wpfWindow.Owner = MainWindow.Single;
wpfWindow.ShowInTaskbar = false;
wpfWindow.Show();
}
代码有效。我假设messenger只保留对该操作的弱引用,因此一旦执行从ShowWpfWindow
传出,该操作可能被垃圾收集。通过将操作设置为类的字段,我将其生命周期与其包含对象的生命周期联系起来。但是,我不想这样做,因为包含对象的生命周期可能小于wpfWindow。
我应该采用什么样的模式来确保不采取近距离行动?