简体   繁体   中英

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?

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM