【发布时间】:2014-01-16 22:15:44
【问题描述】:
我使用 WPF 已经有一段时间了,我在强制从 MainWindow 中仅打开一个窗口实例时遇到了麻烦。我一直在尝试找出我选择的解决方案是否是最好的解决方案,但这个主题的方式似乎并不多。让我怀疑我是不是完全走错了路。
我试图解决的原始问题是只允许打开一个窗口实例,这是我使用单例模型完成的。它最终工作得很好,但我有两个我想打开的窗口,我想要这个功能。我认为创建一个“BaseWindow”来继承会很好,所以我只需要实现一次。这就是我卡住的地方。
我创建了一个非常简单的项目,我试图在其中实现这个想法,但是我在 AboutWindow 的公共构造函数上遇到了保护级别错误,因为 WindowBase 构造函数是私有的。将其更改为 public 允许程序编译,但它似乎“跳过”了具有“InitializeComponent”的 AboutWindow 构造函数。
不过,作为旁注,只允许一个实例的部分确实有效。如果我可以使用 IniliatizeCompotent 让构造函数工作,我将被设置。澄清一下,任何从 WindowBase 派生的窗口都可以同时打开。所以在这种情况下,一次一个 OptionWindow 和一个 AboutWindow。
MainWindow.xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="181" Width="259">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File"></MenuItem>
<MenuItem Header="_Tools">
<MenuItem Header="_Options" ></MenuItem>
</MenuItem>
<MenuItem Header="_Help">
<MenuItem Header="_About" Click="AboutMenuItem_Click"></MenuItem>
</MenuItem>
</Menu>
<Grid>
<TextBlock Text="Content would go here"></TextBlock>
</Grid>
</DockPanel>
</Window>
MainWindow.xaml.cs:
using System.Windows;
namespace WpfApplication1 {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
private void AboutMenuItem_Click(object sender, RoutedEventArgs e) {
AboutWindow.Instance.Show();
}
}
}
关于Window.xaml:
<src:WindowBase x:Class="WpfApplication1.AboutWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:WpfApplication1"
Title="AboutWindow" Height="300" Width="300">
<Grid>
<Label Content="Label" HorizontalAlignment="Left" Margin="84,74,0,0" VerticalAlignment="Top"/>
</Grid>
</src:WindowBase>
关于Window.xaml.cs:
namespace WpfApplication1 {
/// <summary>
/// Interaction logic for AboutWindow.xaml
/// </summary>
public partial class AboutWindow : WindowBase {
public AboutWindow() {
InitializeComponent();
}
}
}
WindowBase.cs:
using System;
using System.Windows;
namespace WpfApplication1 {
public partial class WindowBase : Window {
private static WindowBase instance;
static WindowBase() {
}
private WindowBase() {
Closed += AbstractWindow_Closed;
}
public static WindowBase Instance {
get {
if (instance == null) {
instance = new WindowBase();
} return instance;
}
}
private void AbstractWindow_Closed(object sender, EventArgs e) {
instance = null;
}
}
}
究竟是什么缺失的拼图,还是我走错了路?
【问题讨论】:
-
你的问题是 WindowBase 中的 Instance 属性创建的是 WindowBase 对象,而不是 AboutWindow 对象。
-
首先,使用以下信息更新您的问题:假设您有两个窗口类型 A 和 B,它们都派生自 WindowBase。现在,您是希望只打开一个 A 还是只打开一个 B,还是可以同时打开一个窗口 A 和一个窗口 B?
-
更新了我的问题。我打算选择后者,一个窗口 A 和一个窗口 B 同时打开。在这种情况下,一个 OptionWindow 和一个 AboutWindow。
标签: c# wpf inheritance singleton