如果您真的需要强制窗口的单个实例,那么具有工厂创建方法的静态实例(类似于使用数据库时的单个DataContext实例)肯定是可行的选项之一,就像单个DataContext实例一样。
您也可以编写自己的WindowManager类,尽管这似乎有点过度,而且本质上与此相同(除了Factory方法将在一个类中)。
然而,重新阅读您的帖子,我想知道是否缺少了树林。 您提到的SettingsWindow,其又调用AccountWindow,使我想到您应该只是使用ShowDialog()。 这会以模式打开窗口,这意味着不能与调用窗口(或应用程序中的任何其他窗口)进行交互。 您只需在该对话框中设置属性,在按下“确定”按钮时将DialogResult设置为true,并在父窗口中读取该属性即可。
基本上,您只需像这样使用ShowDialog。 我略去了许多实现细节,例如绑定与硬编码到控件。 这些细节不像看到ShowDialog如何工作那样重要。
为简单起见,假设您有一个名为MyAppOptions的类,它反映了应用程序的选项。 为简单起见,我将省略大部分实现细节,但它可能会实现INotifyPropertyChanged,具有方法和字段和属性等。
public class MyAppOptions
{
public MyAppOptions()
{
}
public Boolean MyBooleanOption
{
get;
set;
}
public String MyStringOption
{
get;
set;
}
}
那么,让我们简化一下,假设您想在按下某个窗口上的按钮时显示一个“选项”对话框。此外,我将假设已经设置了变量以包含您的选项,在启动时加载。
void btnOptions_Click(object sender, RoutedEventArgs e)
}
现在假设OptionsDialog是您项目中创建的一个窗口,它有一个与MyBooleanOption相关的复选框和一个用于MyStringOption的文本框。它还有一个确定按钮和一个取消按钮。代码后端可能会使用绑定,但现在我们将硬编码这些值。
public class OptionsDialog : Window
{
public OptionsDialog(MyAppOptions options)
{
chkBooleanOption.IsChecked = options.SomeBooleanOption;
txtStringOption.Text = options.SomeStringOption;
btnOK.Click += new RoutedEventHandler(btnOK_Click);
btnCancel.Click += new RoutedEventHandler(btnCancel_Click);
}
public MyAppOptions AppOptions
{
get;
set;
}
void btnOK_Click(object sender, RoutedEventArgs e)
{
this.AppOptions.SomeBooleanOption = (Boolean) chkBooleanOption.IsChecked;
this.AppOptions.SomeStringOption = txtStringOption.Text;
this.DialogResult = true;
}
void btnClose_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
}
}
这是一个非常基本的例子,实现细节可以在网上搜索 ShowDialog 了解更多信息。需要记住的重要键是:
- ShowDialog 模态打开窗口,意味着它是您应用程序中唯一可交互的窗口。
- 将 DialogResult 设置为 true 将关闭对话框,可以从调用父级进行检查。
- 将 DialogResult 设置为 false 也会关闭对话框,在这种情况下,您跳过更新调用窗口中的值。
- 单击窗口上的 X 按钮会自动将 DialogResult 设置为 false。
- 您可以在对话框窗口中拥有公共属性,在执行 ShowDialog 前可以设置它们,并且可以在对话框消失后获取值。它在对话框仍然在作用域内时可用。