WPF单实例窗口无法工作

3

我希望在WPF中只有一个窗口实例。

我的窗口代码:

public static bool IsOpen { get; private set; }
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    IsOpen = true;
}

private void Window_Unloaded(object sender, RoutedEventArgs e)
{
    IsOpen = false;
}

我在open函数中的代码

if (MyWindow!= null)
{
    if (MyWindowName.IsOpen)
    {
        MyWindow.Activate();
    }
    else
    {
        MyWindow.Close();
        MyWindow= null;
    }
}
if (MyWindow!= null) return;

MyWindow= new MyWindowName();
MyWindow.Show();
MyWindow.Activate();

但是如果我快速点击3-5次,我能够打开许多窗口实例。

谢谢


1
你不需要 IsOpen 属性,因为 Window.IsLoaded 可以给你完全相同的结果。 - dkozl
使用单例模式。 - JSJ
3个回答

1

当您使用show命令打开窗口时,会存在一定的延迟(此时将处理消息队列以允许处理其他点击事件),然后才会触发窗口加载事件。

一个非常快速而简单的解决方法是将IsOpen赋值移动到show命令之前,您还可以在if语句中使用return来省略第二次检查的需要。

if (MyWindow!= null)
{
    if (MyWindowName.IsOpen)
    {
        MyWindow.Activate();
        return;
    }
    else
    {
        MyWindow.Close();
        MyWindow= null;
    }
}

MyWindow= new MyWindowName();
MyWindow.IsOpen = true;
MyWindow.Show();
MyWindow.Activate();

0

显然你遇到了一个竞争条件。考虑到你需要利用窗口的事件模型,这并不令人惊讶。只需在与声明MyWindow的同一类中声明一个对象,像这样:

private object _lockObj = new object();

然后在进行工作时,这样做:

lock (_lockObj)
{
    if (MyWindow!= null)
    {
        if (MyWindowName.IsOpen)
        {
            MyWindow.Activate();
        }
        else
        {
            MyWindow.Close();
            MyWindow= null;
        }
    }
    if (MyWindow!= null) return;

    MyWindow= new MyWindowName();
    MyWindow.Show();
    MyWindow.Activate();
}

1
那并不一定有效。MyWindow.Show()会很快返回,你仍然可以在窗口加载事件触发之前退出锁定状态。 - Bob Vale

0
这个简单的代码怎么样?
  Window2 win;
        object locker = new Object();
        private void OnShow(object sender, RoutedEventArgs e)
        {
            lock (locker)
            {
                if (win == null)
                    win = new Window2();
                win.Show();
            }
        }

        private void OnHide(object sender, RoutedEventArgs e)
        {
            if (win != null)
                win.Hide();
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接