IViewAwareを実際に実装しなくてもウィンドウを追跡するためのかなり簡単な方法は、一緒に実行されるViewModelsとViewsへの弱参照のディクショナリを保持し、既存のウィンドウがあるかどうかを確認することです。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;
}
}