无需实际实现 IViewAware 即可跟踪您的窗口的一种相当简单的方法是保留对您的 ViewModel 和 View 的弱引用的字典,然后检查您是否已经有一个现有的 Window。可以作为 WindowManager、子类或扩展的装饰器来实现。
假设您实际上并没有计划打开足够多的窗口,即使死掉的 WeakReferences 也会影响性能,那么像下面这样简单的事情应该可以解决问题。如果要长时间运行,那么实施某种清理应该不难。
public class MyFancyWindowManager : WindowManager
{
IDictionary<WeakReference, WeakReference> windows = new Dictionary<WeakReference, WeakReference>();
public override void ShowWindow(object rootModel, object context = null, IDictionary<string, object> settings = null)
{
NavigationWindow navWindow = null;
if (Application.Current != null && Application.Current.MainWindow != null)
{
navWindow = Application.Current.MainWindow as NavigationWindow;
}
if (navWindow != null)
{
var window = CreatePage(rootModel, context, settings);
navWindow.Navigate(window);
}
else
{
var window = GetExistingWindow(rootModel);
if (window == null)
{
window = CreateWindow(rootModel, false, context, settings);
windows.Add(new WeakReference(rootModel), new WeakReference(window));
window.Show();
}
else
{
window.Focus();
}
}
}
protected virtual Window GetExistingWindow(object model)
{
if(!windows.Any(d => d.Key.IsAlive && d.Key.Target == model))
return null;
var existingWindow = windows.Single(d => d.Key.Target == model).Value;
return existingWindow.IsAlive ? existingWindow.Target as Window : null;
}
}