C#WPF - 想要一次打开多个窗口,但每个窗口只能打开一个窗口

时间:2014-03-31 12:36:55

标签: c# wpf window

我是WPF的新手并一直在寻找答案,当然这并不困难?

我创建了一个主窗口,其中包含指向多个窗口的链接,我希望它们可以无模式地并排运行,但我不想打开SAME窗口的多个实例。

简单来说,我可以同时打开Windows A,B,C,但不能打开Windows,A,A,B,C,C。

我需要对我正在尝试打开的窗口执行检查(在本例中为EditSettings)。

如果打开 - 激活它

如果没有打开,请打开它。

我在Main中有以下代码,但无效。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void MenuItem_Click(object sender, RoutedEventArgs e)
    {
        EditSettings winEditSettings = new EditSettings();
        string isOpen = null;
        if (isOpen == "true")
        {
            winEditSettings.Activate();
        }
        else
        { 
            winEditSettings.Show();
            isOpen = "true";
        }
    }

}

现在我知道这个逻辑有什么问题 - 每次按下按钮打开EditSettings,它的设置isOpen再次为null。如果我没有为isOpen设置值,则If条件会中断。

我可以将变量'isOpen'初始化为MenuItem_Click方法之外的公共变量,但是我认为我需要为我创建的每个窗口创建一个isOpen变量!当然有更好的方法吗?

我尝试的另一个选项是:

    private void MenuItem_Click(object sender, RoutedEventArgs e)
    {
        EditSettings winEditSettings = new EditSettings();
        if (winEditSettings.IsLoaded)
        {
            winEditSettings.Activate();
        }
        else { winEditSettings.Show(); }

我无法弄清楚为什么这不起作用,我试过isVisible,isLoaded,isActive - 没有什么能阻止窗口不止一次打开。感谢您的帮助!

4 个答案:

答案 0 :(得分:1)

有些人可能会对这个想法有所帮助,但每当我需要这样做时,我都会将子窗口对象作为应用程序的一部分。然后,在MenuItem_Click()中,测试winEditSettings是否为null,而不是。{/ p>

它仍然是每个窗口的成员变量(就像您的临时isOpen解决方案一样),但如果您需要在窗口之间桥接信息,那么将窗口对象提供后可能会有优势。在我的情况下,我们希望能够将所有子窗口关闭在一起,这些(最简单的)意味着在中心位置跟踪这些对象。

或者,如果您希望设置完全解耦,您可以采用类似单一的方法并将逻辑放入子窗口类中。具体来说,您可以调用EditSettings.Activate并让班级跟踪是否需要创建窗口或现有窗口Show() n。

如果我将代码交给你重写,我就把它移到这样的地方:

private static EditSettings winEditSettings = null;

public static void WakeUp()
{
    if (winEditSettings == null)
    {
        winEditSettings = new EditSettings();
    }
    winEditSettings.Activate();  // This may need to be inside the block above
    winEditSettings.Show();
}

这两个都是类(static)的一部分,而不是实例。因此,您的应用程序对象在原始EditSettings.WakeUp()内调用MenuItem_Click(),并且实际上从未实际看到子窗口。

如果您稍后改变对分离式架构的看法,顺便说一下,您可以为get添加winEditSettings访问者并让每个人都相当高兴。

答案 1 :(得分:1)

               if (_adCst == null)
               {
            _adCst = new AddCustomerPage();
            _adCst.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
            _adCst.WindowState = System.Windows.WindowState.Normal;
            _adCst.ResizeMode = System.Windows.ResizeMode.NoResize;
            _adCst.Activate();  // This may need to be inside the block above
            _adCst.Show();
               }

              else
        {
            if (!_adCst.IsLoaded == true) 
            {
                _adCst = new AddCustomerPage();
                _adCst.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
                _adCst.WindowState = System.Windows.WindowState.Normal;
                _adCst.ResizeMode = System.Windows.ResizeMode.NoResize;
                _adCst.Show();
            }

            _adCst.Activate();
        }

答案 2 :(得分:0)

对于有这个问题的其他人,我找到了另一个解决方案 - 除了它没有设法将打开的窗口置于前面(激活)之外。但是,它确实会阻止多次打开同一个窗口。

        foreach (Window n in Application.Current.Windows)
            if (n.Name == "winEditSettings")
            { winEditSettings.Activate(); }
            else
            { winEditSettings.Show(); }

有人可以通过Activate()来推测窗口没有被带到前面的原因吗?

修改

对于有这个问题的其他人,将winEditSettings.Activate()放在foreach循环之外会做我想要实现的所有事情:

        foreach (Window n in Application.Current.Windows)
            if (n.Name == "winEditSettings")
            { }
            else
            { winEditSettings.Show(); }

    winEditSettings.Activate(); 

这将阻止同一窗口的多个实例打开,如果用户尝试重新打开窗口,则会将窗口置于前面。

答案 3 :(得分:0)

我的建议是你设置某种形式的柜台。这将阻止打开多个窗口实例。

    int windowOpen = 1;

    private void button_Click(object sender, RoutedEventArgs e)
    {        
        if (windowOpen == 1) 
        {
            WindowA winA = new WindowA();
            winA.Show();
            windowOpen++; //increments windowOpen by 1, windowOpen will now = 2
        }
        else if (windowOpen > 1)
        {
            MessageBox.Show("Window is already open"); 
        }
    }

我希望这会有所帮助。