微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C#WPF如何强制单个窗口实例

我想知道什么是最好的方式(最优雅)在 WPF中为每个应用程序提供给定窗口的单个实例.

我是.NET和WPF的新手,我想到的看起来很跛脚.

private static readonly Object MUTEX = new Object();
private static Aboutwindow INSTANCE;

public static Aboutwindow GetorCreate() {
    lock (MUTEX) {
        if (INSTANCE == null) {
            INSTANCE = new Aboutwindow();
        }
        INSTANCE.Show();
        return INSTANCE;
    }
}

private Aboutwindow() {
    InitializeComponent();
}

private void Aboutwindow_Closed(object sender,EventArgs e) {
    // the Closed events are handy for me to update values across
    // different windows.
    lock (MUTEX) {
        INSTANCE = null;
    }
}

这是…这看起来像是彻底的废话.必须有一些方法以更优雅的方式实现同​​样的目标,对吗?

PS:我经常使用Closed事件来更改其他打开的窗口中的值.例如我有SettingsWindow与“帐户”按钮.当我按下该按钮时,会弹出Accountwindow.当我关闭Acountwindow时,我想在SettingsWindow中改变(标签).因此不断创建窗口.
此外,关闭是您总是要处理的,因为窗口框架上的X按钮…

解决方法

如果您真的需要强制执行一个窗口的单个实例,那么使用工厂创建方法的静态实例(您所拥有的一些风格)当然是一个可行的选项,就像使用数据库时的单个DataContext实例一样.

您也可以编写自己的WindowManager类,尽管这似乎是过分的,但基本上是一样的(除了Factory方法将在一个类中).

但是,重新阅读你的帖子,我想知道这是否是树木失踪森林的情况.你提到的SettingsWindow又调用了Accountwindow,让我觉得你应该使用ShowDialog().这将以模态方式打开窗口,这意味着不能与调用窗口(或应用程序中的任何其他窗口)进行交互.您只需在该对话框中设置一个属性,当按下OK按钮时将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)
{
    MyAppOptions options = new MyAppOptions();
    options.MyBooleanoption = mSomeBoolean;
    options.MyStringOption = mSomeString;

    OptionsDialog optionsDialog = new optionsDialog(options);
    if (optionsDialog.ShowDialog() == true)
    {
        // Assume this function saves the options to storage
        // and updates the application (binding) appropriately
        SetAndSaveOptions(optionsDialog.AppOptions);
    }
}

现在假设OptionsDialog是您在项目中创建的一个窗口,并且它有一个与MyBooleanoption相关的CheckBox,以及一个用于MyStringOption的TextBox.它还有一个确定按钮和一个取消按钮.代码隐藏可能会使用Binding,但现在我们将硬编码这些值.

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 is the key step - it will close the dialog and return 
        // true to ShowDialog
        this.DialogResult = true;
    }

    void btnClose_Click(object sender,RoutedEventArgs e)
    {
        // this will close the dialog and return false to ShowDialog
        // Note that pressing the X button will also return false to ShowDialog
        this.DialogResult = false;
    }
}

就实现细节而言,这是一个非常基本的例子.在线搜索ShowDialog了解更多详情.要记住的重要关键是:

> ShowDialog以模态方式打开窗口,这意味着它是你唯一的窗口可以互动的应用程序用.>将DialogResult设置为true将关闭对话框,这可以是从主叫父母检查.>将DialogResult设置为false将会也关闭对话框,在这种情况下你跳过更新的值呼叫窗口.>按X按钮在窗口上自动设置DialogResult为false>您可以在对话框窗口中具有可以在执行ShowDialog之前设置的公共属性,并且可以在对话框消失后获取值.该对话框仍然在范围内可用.

原文地址:https://www.jb51.cc/csharp/95596.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐