关闭WPF MVVM中的窗口

3

我一直在使用WPF和MVVM开发一个项目。在我的项目中的某个部分,我使用了以下代码来关闭窗口。代码可以正常运行,但是我还不理解其中的逻辑。我的代码如下:

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

为什么需要使用FirstOrDefault()方法?

FirstOrDefault是从集合中获取第一个项目的安全方式。 - kidshaw
你调用Where方法返回一个可枚举类型,意味着它可以包含很多元素,然后你只选择第一个。将其替换为FirstOrDefault(win => win is DisplayView).Close()。 - Maximus
2个回答

3

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

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

这基本上相当于:

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

此外,先调用 FirstOrDefault() 再调用 "Close" 有点儿傻。FirstOrDefault 类似于 First,不同之处在于如果没有元素,它会返回 null 而不是抛出异常 -- 但在这种情况下,你仍然会因为调用 null 对象的 "Close" 方法而抛出异常。
因此,我会这样写:
App.Current.Windows.OfType<DisplayView>().First().Close();

如果您想要验证确实存在一个DisplayView实例,并且在这种情况下防止异常发生,那么可以使用以下代码:

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

0

让我们来分解一下:

  • App.Current:获取正在运行的 WPF 应用程序(我认为应该是 Application.Current
  • .Windows.Cast<Window>():获取窗口列表,但由于这是一个未经类型化的集合,因此需要将其强制转换为强类型以使用所有LINQ运算符
  • .Where(win => win is 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();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接