【问题标题】:Single Instance Window WPF not working单实例窗口 WPF 不起作用
【发布时间】:2013-06-20 13:16:39
【问题描述】:

我只想在 WPF 中有一个我的 Window 实例。

我在窗口中的代码:

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;
}

我在打开函数中的代码

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 次,我可以打开许多窗口实例。

谢谢

【问题讨论】:

  • 你不需要IsOpen 属性,因为Window.IsLoaded 会给你完全相同的结果
  • 采用单例模式。

标签: c# .net wpf


【解决方案1】:

在您使用 show 命令打开窗口(然后将处理允许处理其他点击的消息队列)与触发 windows 加载事件之间会有延迟。

一个非常快速和肮脏的解决方法是将 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();

【讨论】:

    【解决方案2】:

    很明显,您遇到了比赛条件。考虑到您必须利用Window 的事件模型,这并不奇怪。只需在声明 MyWindow 的同一类中声明 object,如下所示:

    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();
    }
    

    【讨论】:

    • 那不一定行得通。 MyWindow.Show() 将快速返回,您仍然可以在窗口加载事件触发之前退出锁定。
    【解决方案3】:

    这个简单的代码怎么样。

      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();
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-21
      • 2011-04-28
      • 1970-01-01
      • 2018-12-17
      • 1970-01-01
      相关资源
      最近更新 更多