C# 关闭WPF MVVM中的窗口

C# 关闭WPF MVVM中的窗口,c#,wpf,linq,mvvm,C#,Wpf,Linq,Mvvm,我已经在一个WPF和MVVM项目上工作了一段时间了。在项目的一部分中,我使用以下代码关闭了一个窗口。代码可以工作,但是,我还不理解代码背后的逻辑。我的代码是: App.Current.Windows.Cast<Window>() .Where(win => win is DisplayView).FirstOrDefault() .Close(); App.Current.Windows.Cast() .Where(win=>win是DisplayView).

我已经在一个WPF和MVVM项目上工作了一段时间了。在项目的一部分中,我使用以下代码关闭了一个窗口。代码可以工作,但是,我还不理解代码背后的逻辑。我的代码是:

App.Current.Windows.Cast<Window>()
    .Where(win => win is DisplayView).FirstOrDefault()
    .Close();
App.Current.Windows.Cast()
.Where(win=>win是DisplayView).FirstOrDefault()
.Close();
为什么需要FirstOrDefault()?

我们来拆分它:

  • App.Current
    :获取正在运行的WPF应用程序(我认为应该是
    application.Current
  • .Windows.Cast()
    :获取窗口列表,但由于这是一个非类型集合请将其设置为强类型以使用所有LINQ运算符
  • .Where(win=>win是DisplayView)
    :LINQ运算符用于筛选窗口列表,并仅保留类型为
    DisplayView的窗口
  • .FirstOrDefault()
    :获取此集合的第一个元素,如果没有,则获取
    null
  • .Close()
    :关闭我们得到的窗口,这是很危险的,因为如果没有找到任何窗口,它将以
    NullReferenceException
    爆炸
以下是一种更安全的方法:

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

if (view != null)
{
    view.Close();
}
DisplayView-view=App.Current.Windows.Cast()
.Where(win=>win是显示视图)
.FirstOrDefault();
如果(视图!=null)
{
view.Close();
}

它只使用一些Linq
IEnumerable
扩展从与给定类型匹配的集合中获取第一项,然后在该实例上调用
Close
。这实际上是不必要的冗长,因为:

App.Current.Windows.Cast<Window>()
    .Where(win => win is DisplayView)
var displayViews = App.Current.Windows.OfType<DisplayView>();
if (displayViews.Any())
    displayViews.First().Close();
如果要验证是否确实存在DisplayView实例,并防止出现异常,则可以使用以下方法:

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

First或default是从集合中获取第一项的安全方法。您可以调用Where返回可枚举类型,这意味着可以包含许多元素,然后只选择First。按照以下步骤替换它FirstOrDefault(win=>win是DisplayView)
var displayViews = App.Current.Windows.OfType<DisplayView>();
if (displayViews.Any())
    displayViews.First().Close();