6

I have this click event in my main window to open a new window

private void Button_Click(object sender, RoutedEventArgs e)
{
    cm = new CanalesMain();

    cm.Show();

    cm.Canales.setValues();

}

My cm variable is defined as a member class in my main window because I need to load/refresh the setValues() method every 5 minutes (there's a TimeSpan and a EventHandler for that)

The thing is, in my "refresh data" method I have this if statement to ask if the cm variable is loaded and is not null (I mean, if the window was ever opened or if is opened, ask if isn't closed)

if (cm!=null && cm.IsLoaded)
{
    cm.Canales.setValues();
}

Is this the correct or best way to ask if my window is open?

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Naty Bizz
  • 2,262
  • 6
  • 33
  • 52
  • 1
    Does it work? The answer to that is the answer to your question. If it does work, what don't you like about the implementation. IsLoaded is the _de facto_ way to query a window handle. – Gusdor Oct 29 '13 at 14:06

4 Answers4

13

Strictly speaking no, it's not the right way. IsLoaded doesn't mean that Window is visible, just loaded (even if this may be equivalent in most of scenarios but it means this window has been created once, it has a handle, no mention to its visibility).

What you have to check is the Visibility property (it's what, finally, Show() will change), it'll be Visible if the Window is currently visible or Hidden if it has not been loaded (or it has been loaded and it still is but actually hidden).

To summarize:

if (cm != null && cm.Visibility == Visibility.Visible)
{
}

Please note that if Window is visible then it's implicit it has been loaded (it has a handle) but it's not true the vice-versa (a loaded window may not be visible and maybe it was even not in the past).

Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
  • I'll defer to you, since you answered first. It's worth mentioning that a Window's `Visibility` will remain `Visible` after it is closed, while `Loaded` will revert to `false`. Also, a window may not have been actually rendered (and visible to the user) despite being in both `Loaded` and `Visible` states. The only way to ensure a window has been rendered at least once is to handle its `ContentRendered` event. – Mike Strobel Oct 29 '13 at 14:19
  • @MikeStrobel IsLoaded won't ever revert to false unless object has been disposed. It'll go Collapsed when closed. I agree it doesn't mean it has been rendered or not, he didn't ask so I didn't even mention it (I would usually do a much more rough and easy check using RenderSize property instead of handling ContentRendered event but I know, it's not strictly correct). – Adriano Repetti Oct 29 '13 at 14:36
  • The test case I just wrote suggests otherwise. The properties both retain their values immediately after `Close()`; after a subsequent layout update, the visual tree has been unloaded, and `IsLoaded` returns `false`. `Visibility` remained `Visible` the entire time. – Mike Strobel Oct 29 '13 at 14:47
  • @MikeStrobel well, according to MSDN it shouldn't be but...if your test proves that...OK! – Adriano Repetti Oct 29 '13 at 15:03
2

There is another way of checking which Windows are currently active:

foreach (Window window in Application.Current.Windows)
{ 
    // Check for your Window here
}

If your Window is of a particular type, then you can do this instead:

foreach (Window window in Application.Current.Windows.OfType<YourWindow>())
{ 
    // Do something with your Window here
}

Your Window will not appear here before it is displayed.

Sheridan
  • 68,826
  • 24
  • 143
  • 183
0

I think extension method will be very useful in that case, try this:

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

Which gives you ability to make call on every window like this:

var wind = new ChildWindow();
wind.ShowDialog();
var isOpened = wind.IsOpened();

Also you can check out this: How do I know if a WPF window is opened

More info about Application.Windows

Community
  • 1
  • 1
testCoder
  • 7,155
  • 13
  • 56
  • 75
0

If you call myWindow.Show() and myWindow.Close(), myWindow.IsLoaded should get you a value that you can use to indicate if the window is open or not.

Arnel
  • 332
  • 2
  • 15