Closing a window in WPF MVVM

I have been working on a project with WPF and MVVM for a while now. In part of my project, I used the following code to close the window. However the code works, but I don't understand the logic of the code yet. My code:

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

      

Why is FirstOrDefault () required?

+3


source to share


2 answers


It just uses some Linq extensions IEnumerable<T>

to get the first item from the collection that matches the given type and then calls Close

on that instance. This is actually uselessly verbose because it is:

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

      

is more or less equivalent to this:

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

      

Also, a call FirstOrDefault()

followed by "Close" is a bit silly. FirstOrDefault is similar First

, except that it returns null instead of throwing an exception if there are no items, but it throws an exception anyway because you are calling Close on a null object.




So I would write it like this:

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

      

If you want to check that there is actually a DisplayView instance and prevent an exception in that case, you can use this:

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

      

+3


source


Let's break it down:

  • App.Current

    : get the current WPF app (must be Application.Current

    my guess)
  • .Windows.Cast<Window>()

    : get a list of windows, but since this is an untyped collection it is heavily typed to use all LINQ operators
  • .Where(win => win is DisplayView)

    : LINQ operator to filter the list of windows and keep only those specified DisplayView

  • .FirstOrDefault()

    : get the first element of this collection, or null

    if not
  • .Close()

    : close the window we got, it is dangerous as it will blow with help NullReferenceException

    if none is found.


Here's a safer approach:

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

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

      

0


source







All Articles