user3864949
user3864949

Reputation: 35

Closing a window in WPF MVVM

I have been working on a project with WPF and MVVM for a while now. In a part of my project, I used the following code to close a window. The code works, however, I do not understand the logic behind the code yet. My code is:

App.Current.Windows.Cast<Window>()
    .Where(win => win is DisplayView).FirstOrDefault()
    .Close();

Why is FirstOrDefault() required?

Upvotes: 3

Views: 278

Answers (2)

McGarnagle
McGarnagle

Reputation: 102743

It just uses some Linq IEnumerable<T> extensions to get the first item from a collection that matches a given type, then calls Close on that instance. It is actually needlessly verbose, because this:

App.Current.Windows.Cast<Window>()
    .Where(win => win is DisplayView)

is more or less equivalent to this:

App.Current.Windows.OfType<DisplayView>()

Also, calling FirstOrDefault() followed by "Close" is a bit silly. FirstOrDefault is like First, except it returns null instead of throwing an exception if there are no elements -- but in that case it would throw an exception anyway because you'd be calling "Close" on a null object.


So I would write it like this:

App.Current.Windows.OfType<DisplayView>().First().Close();

If you wanted to verify that there is in fact a DisplayView instance, and prevent an exception in that case, then you could use this:

var displayViews = App.Current.Windows.OfType<DisplayView>();
if (displayViews.Any())
    displayViews.First().Close();

Upvotes: 3

Pragmateek
Pragmateek

Reputation: 13354

Let's split it:

  • App.Current: get the running WPF application (should be Application.Current I think)
  • .Windows.Cast<Window>(): get the list of windows but as this is an untyped collection make it strongly typed to use all the LINQ operators
  • .Where(win => win is DisplayView): LINQ operator to filter the windows list and only keep those of type DisplayView
  • .FirstOrDefault(): get the first element of this collection or null if there is none
  • .Close(): close the window we got, this is dangerous as it will blow with a NullReferenceException if none was found

Here is a safer approach:

DisplayView view = App.Current.Windows.Cast<Window>()
                                      .Where(win => win is DisplayView)
                                      .FirstOrDefault();

if (view != null)
{
    view.Close();
}

Upvotes: 0

Related Questions