如何泛化代码以在 WPF 应用程序中每个 Window 只允许一个实例
How to generalize code to allow only one instance per Window in WPF application
注意:因为我的问题被标记为重复,
这里有更多细节:
有没有办法封装代码,而不用为每个 class 写 x 次? (这不是关于 MainWindow!这是关于多个 window classes!)
我的 WPF 应用程序包含多个 Windows(例如 Win1、Win2、Win3、..)。我希望其中一些不能同时打开多个实例。所以假设如果 Win1 已经打开并且用户单击新的 Window,我会将 Win1(仍然打开)带到 UI 的前面。
还需要可以同时打开多个(但不同Windows打开)如Win1和Win2!
我在Win1中用这个方法解决了-class:
private static Win1 openWindow = null;
在 OnLoaded 事件中:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
if (Win1.openWindow != null)
{
Win1.openWindow.Topmost = true;
if (Win1.openWindow.WindowState == WindowState.Minimized)
Win1.openWindow.WindowState = System.Windows.WindowState.Normal;
Win1.openWindow.Activate();
Win1.openWindow.Topmost = false;
this.Close();
}
else Win1.openWindow = this;
最后在 OnClosing-Event 中:
private void Window_Closing(object sender, CancelEventArgs e)
{
if (Win1.openWindow == this)
Win1.openWindow = null;
}
像其他 20 个 Win-classes 一样,我需要这种行为。有没有更好的方法来实现它,而无需每手添加 20 次?
我试着写一个自定义的Window class 并用它来继承,但是静态字段需要特定的类型(例如Win1)。
欢迎任何建议!
谢谢
@Ben Bancroft 在此处的示例中提供了解决方案:
OnlyOneOfEachTypeOfWindow-示例
正如@NPras 告诉我的,它使用 Factory-Pattern 来解决问题,主要是这里的 class:
public static class WindowManager
{
public static T GetWindow<T>()
{
var t = Application.Current.Windows.OfType<T>().FirstOrDefault();
if (t == null)
{
t = (T)Activator.CreateInstance(typeof(T));
}
return t;
}
public static T CreateOrFocusWindow<T>()
{
var t = GetWindow<T>();
if (t is Window)
{
var window = t as Window;
if (window.Visibility != Visibility.Visible)
window.Show();
if (window.WindowState == WindowState.Minimized)
window.WindowState = WindowState.Normal;
window.Focus();
}
return t;
}
}
然后您可以像这样使用它:
var window = WindowManager.CreateOrFocusWindow<Window1>();
var window = WindowManager.CreateOrFocusWindow<Window2>();
感谢您的帮助!
注意:因为我的问题被标记为重复, 这里有更多细节: 有没有办法封装代码,而不用为每个 class 写 x 次? (这不是关于 MainWindow!这是关于多个 window classes!)
我的 WPF 应用程序包含多个 Windows(例如 Win1、Win2、Win3、..)。我希望其中一些不能同时打开多个实例。所以假设如果 Win1 已经打开并且用户单击新的 Window,我会将 Win1(仍然打开)带到 UI 的前面。 还需要可以同时打开多个(但不同Windows打开)如Win1和Win2!
我在Win1中用这个方法解决了-class:
private static Win1 openWindow = null;
在 OnLoaded 事件中:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
if (Win1.openWindow != null)
{
Win1.openWindow.Topmost = true;
if (Win1.openWindow.WindowState == WindowState.Minimized)
Win1.openWindow.WindowState = System.Windows.WindowState.Normal;
Win1.openWindow.Activate();
Win1.openWindow.Topmost = false;
this.Close();
}
else Win1.openWindow = this;
最后在 OnClosing-Event 中:
private void Window_Closing(object sender, CancelEventArgs e)
{
if (Win1.openWindow == this)
Win1.openWindow = null;
}
像其他 20 个 Win-classes 一样,我需要这种行为。有没有更好的方法来实现它,而无需每手添加 20 次? 我试着写一个自定义的Window class 并用它来继承,但是静态字段需要特定的类型(例如Win1)。
欢迎任何建议!
谢谢
@Ben Bancroft 在此处的示例中提供了解决方案:
OnlyOneOfEachTypeOfWindow-示例
正如@NPras 告诉我的,它使用 Factory-Pattern 来解决问题,主要是这里的 class:
public static class WindowManager
{
public static T GetWindow<T>()
{
var t = Application.Current.Windows.OfType<T>().FirstOrDefault();
if (t == null)
{
t = (T)Activator.CreateInstance(typeof(T));
}
return t;
}
public static T CreateOrFocusWindow<T>()
{
var t = GetWindow<T>();
if (t is Window)
{
var window = t as Window;
if (window.Visibility != Visibility.Visible)
window.Show();
if (window.WindowState == WindowState.Minimized)
window.WindowState = WindowState.Normal;
window.Focus();
}
return t;
}
}
然后您可以像这样使用它:
var window = WindowManager.CreateOrFocusWindow<Window1>();
var window = WindowManager.CreateOrFocusWindow<Window2>();
感谢您的帮助!