1

I have a button that opens a Window.

If the button is pressed again, it opens a duplicate of the same window.

info = new Info();
info.Owner = Window.GetWindow(this);
info.Show();

How do you check if the Window is already open, and deny a duplicate from being opened again?

I can't use info.ShowDialog() because it disables the Main Window.


Solutions that have not worked:

Info info = new Info();

if (!info.IsActive)
{
    info = new Info();
    info.Owner = Window.GetWindow(this);
    info.Show();
}

Info info = new Info();

if (info.Visibility != Visibility.Visible)
{
    info.Owner = Window.GetWindow(this);
    info.Show();
}

public static bool IsWindowOpen<T>(string name = "") where T : Window
{
    return string.IsNullOrEmpty(name)
           ? Application.Current.Windows.OfType<T>().Any()
           : Application.Current.Windows.OfType<T>().Any(w => w.Name.Equals(name));
}

private void buttonInfo_Click(object sender, RoutedEventArgs e)
{    
    if (!IsWindowOpen<Window>("Info"))
    {
        Info info = new Info();
        info.Owner = Window.GetWindow(this);
        info.Show();
    }
}
Matt McManis
  • 4,475
  • 5
  • 38
  • 93
  • 1
    You are keep creating new instance of `Info` and based your check on the new instance. You should declare you `Info` window in your class level, and check that. – Bolu Sep 12 '16 at 15:29

3 Answers3

2

The sensible approach is to just keep track of the Window instance so you don't have to find it back later. Add a field:

    private Info infoWindow;

If it is null then you know that the window doesn't exist yet, so you'll want to create it. Use the Closed event to set the variable back to null. If it is not null then you want to make sure that the window gets restored. So:

    private void button_Click(object sender, RoutedEventArgs e) {
        if (infoWindow == null) {
            infoWindow = new Info();
            infoWindow.Closed += (s, ea) => infoWindow = null;
            infoWindow.Owner = this;   // optional
            infoWindow.Show();
        }
        else {
            if (infoWindow.WindowState == WindowState.Minimized) {
                infoWindow.WindowState = WindowState.Normal;
            }
            infoWindow.Activate();
        }
    }

And you probably also want to close the window automatically when the window that contains the button is closed:

    private void Window_Closed(object sender, EventArgs e) {
        if (infoWindow != null) infoWindow.Close();
    }
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • This works really well. Though the Info window loses focus if the Main window button is clicked again, which is the proper function, but @zaylau answer kept the focus on the Info window, which I want to use in this case. – Matt McManis Sep 12 '16 at 15:58
  • If you want to keep the focus on the info window then you must use ShowDialog(). Well, you already dismissed that. I guess what you really mean is that you want to keep it above the main window, set the Owner property. – Hans Passant Sep 12 '16 at 15:59
  • Actually you are right, I had put the Owner property on the other solution and that's what was keeping the focus. Your answer works identical. – Matt McManis Sep 12 '16 at 16:05
2

Create a form only when value is not null. If the form was closed put the value back to null with the FormClosed event.

public static Info info;

if(info == null){
  info = new Info();
  info.Show();
}

put an event form close on the info form

 private void info_FormClosed(object sender, FormClosedEventArgs e)
 {
    MainForm1.info = null;
 }

It works for me

Timon Post
  • 2,779
  • 1
  • 17
  • 32
  • Is this for WinForms? I'm actually using WPF, but I'll keep this in mind. – Matt McManis Sep 12 '16 at 15:53
  • Yes it is for windows forms but if you search for form closing event for WPF this should work as well. maybe try this http://stackoverflow.com/questions/3683450/handling-the-window-closing-event-with-wpf-mvvm-light-toolkit – Timon Post Sep 12 '16 at 16:01
0

You could use .IsLoaded field or bind the .ContentRendered event

Edit 1 -

Window1:

public class Window1 : Window
{
    private Info info = null;
    private Boolean IsInfoOpened = false;

    protected void OpenInfo()
    {
        if (this.IsInfoOpened) return;
        this.info = new Info();
        this.info.ContentRendered += delegate { this.IsInfoOpened = true; };
        this.info.Closed += delegate { this.IsInfoOpened = false; }
        this.info.Show();
    }
}
Zay Lau
  • 1,856
  • 1
  • 10
  • 17