45

In a WPF window, how do I know if it is opened?

My goal to open only 1 instance of the window at the time.

So, my pseudo code in the parent window is:

if (this.m_myWindow != null)
{
    if (this.m_myWindow.ISOPENED) return;
}

this.m_myWindow = new MyWindow();
this.m_myWindow.Show();

EDIT:

I found a solution that solves my initial problem. window.ShowDialog();

It blocks the user from opening any other window, just like a modal popup. Using this command, it is not necessary to check if the window is already open.

guilhermecgs
  • 2,913
  • 11
  • 39
  • 69

10 Answers10

95

In WPF there is a collection of the open Windows in the Application class, you could make a helper method to check if the window is open.

Here is an example that will check if any Window of a certain Type or if a Window with a certain name is open, or both.

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

Usage:

if (Helpers.IsWindowOpen<Window>("MyWindowName"))
{
   // MyWindowName is open
}

if (Helpers.IsWindowOpen<MyCustomWindowType>())
{
    // There is a MyCustomWindowType window open
}

if (Helpers.IsWindowOpen<MyCustomWindowType>("CustomWindowName"))
{
    // There is a MyCustomWindowType window named CustomWindowName open
}
sa_ddam213
  • 42,848
  • 7
  • 101
  • 110
  • It is a good solution! Thanks. But since I found another way to solve my problem, I will not use it. – guilhermecgs Apr 25 '13 at 12:46
  • @guilhermecgs What easier way did you find to solve your problem? – estebro Jul 31 '14 at 15:19
  • 1
    @estebro - I used a modal popup. My requirement was to avoid user interaction with other opened windows. So, a modal popup does that by definition. http://stackoverflow.com/questions/499294/how-do-make-modal-dialog-in-wpf – guilhermecgs Jul 31 '14 at 17:52
  • is there a way to use this for a wpf window that is running on another thread? If yes, can someone post a simple example? – konrad Sep 27 '15 at 22:24
  • 3
    According to documentation `Application.Current.Windows` is a list of all Windows that have been instantiated (not necessarily open) – Robert Snyder Jan 11 '17 at 13:34
  • Can someone tell me what libraries I need to add as imports to use "Windows" and "Application" ? VS is suggesting "OpenQA.Selenium.IWindow" for Windows and "System.Net.Mime.MediaTypeNames." for Application but when I choose that I get an error saying "System.Net.Mime.MediaTypeNames." does not contain a definition of Current – Monnie_tester Dec 18 '20 at 14:37
15

You can check if m_myWindow==null and only then create and show window. When the window closes set the variable back to null.

    if (this.m_myWindow == null)
    {
           this.m_myWindow = new MyWindow();
           this.m_myWindow.Closed += (sender, args) => this.m_myWindow = null;           
           this.m_myWindow.Show();
    }
Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Jurica Smircic
  • 6,117
  • 2
  • 22
  • 27
  • Similiar solution to @ofstream – guilhermecgs Apr 25 '13 at 12:48
  • Just out of interest, is there a memory leak in this code as we never remove the closed event handler or does setting the object to null remove all event handlers? – JKennedy Apr 07 '15 at 11:39
  • @user1 i know this is old, but yes; yes it does create memory leak. i'm currently trying to find a way to solve the problem of the memory leak in a tray application that spawns different windows and synchronizes them on on a variable. – JoshHetland Apr 14 '15 at 03:48
  • 1
    @JoshHetland Could you not remove the event handler of the window in the close event? You may been to use an explicit method rather than an anonymous one to do this. I think that would get rid of the memory leak – JKennedy Apr 14 '15 at 07:37
  • Yes, but i haven't found a way to do that when using a lamda which i was using extensively. – JoshHetland Apr 14 '15 at 13:34
9

Here is another way to achieve this using LINQ.

using System.Linq;

...

public static bool IsOpen(this Window window)
{
    return Application.Current.Windows.Cast<Window>().Any(x => x == window);
}

Usage:

bool isOpen = myWindow.IsOpen();
Mike Eason
  • 9,525
  • 2
  • 38
  • 63
2

If you need to activate the window if it is found, you can use the code below:

//activate a window found
//T = Window

 Window wnd = Application.Current.Windows.OfType<T>().Where(w => w.Name.Equals(nome)).FirstOrDefault();
 wnd.Activate();
1

Put a static bool in your class, named _open or something like that. In the constructor then do this:

if (_open)
{
    throw new InvalidOperationException("Window already open");
}
_open = true;

and in the Closed event:

_open = false;
Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
It'sNotALie.
  • 22,289
  • 12
  • 68
  • 103
1

Is that you search ?

if (this.m_myWindow != null)
{
    if (this.m_myWindow.IsActive) return;
}

this.m_myWindow = new MyWindow();
this.m_myWindow.Show();

If you want a singleton, you should read this : How can we create a Singleton Instance for a Window?

Community
  • 1
  • 1
Floc
  • 668
  • 8
  • 16
0
    void  pencereac<T> (int Ops) where T : Window , new()
    {
        if (!Application.Current.Windows.OfType<T>().Any()) // Check is Not Open, Open it.
        {
           var wind = new T();
            switch (Ops)
            {
                case 1:
                    wind.ShowDialog();
                    break;
                case 0:
                    wind.Show();
                    break;
            }
        }
        else Application.Current.Windows.OfType<T>().First().Activate(); // Is Open Activate it.
    }

Kullanımı:

void Button_1_Click(object sender, RoutedEventArgs e)
{
  pencereac<YourWindow>(1);
}
0

This works if you want to Check if the Second Form is already Open and avoidt opening it again on buttong Click.

int formcheck = 0;
private void button_click()
{
   Form2Name myForm2 = new Form2Name();
   if(formcheck == 0)
   {
      myForm2.Show(); //Open Form2 only if its not active and formcheck == 0
      // Do Somethin

      formcheck = 1; //Set it to 1 indicating that Form2 have been opened
   {   
{
Chad
  • 141
  • 9
-1
public bool IsWindowOpen<T>(string name = "") where T : Window
{
    return Application.Current.Windows.OfType<T>().Any(w => w.GetType().Name.Equals(name));               
}
Jim Buck
  • 2,383
  • 23
  • 42
-1
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private static WindowNew? windowNew;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void BtnOpenWindow_Click(object sender, RoutedEventArgs e)
        {
            //if the window is null, create
            if (windowNew == null)
            {
                windowNew = new WindowNew
                {
                    Owner = this
                };
                windowNew.Show();
            }
            else
            {
                //else if not null, but cant be activated
                if (!windowNew.Activate())
                {
                    //failed, set to null
                    windowNew = null;
                    //call rekursiv this method again
                    BtnOpenWindow_Click(sender, e);
                }
            }
        }
    }
  • Answer needs supporting information Your answer could be improved with additional supporting information. Please [edit](https://stackoverflow.com/posts/76257273/edit) to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](https://stackoverflow.com/help/how-to-answer). – moken May 19 '23 at 01:54