【问题标题】:Managing multiple WPF views in an application在应用程序中管理多个 WPF 视图
【发布时间】:2010-12-22 03:10:27
【问题描述】:

所以我看到 WPF 中存在一个导航服务,用于维护通过应用程序的流程。我并不真正在市场上寻求后退和前进类型的功能。我只是在寻找一种在按下特定视图上的按钮时在视图之间切换的好方法。我正在使用 MVVM,所以我不确定是否可以让 App.xaml.cs 可能包含每个 View 或 ViewModel 的副本,并让 ViewModel 命令调用 App.xaml.cs 来进行切换。也许我应该只处理按钮上的 Click 事件并做一些 this.Close(); NewWindow.Show();.
与 WPF 中的许多东西一样,这对我来说并不直观,尽管可能有几个简单的解决方案。

谢谢!

【问题讨论】:

  • 您是否在使用任何应用程序框架,例如 Prism?你在使用 IoC 或类似的东西吗?这将有助于决定一种方法。
  • 没有统一、IoC 或任何东西。我试图坚持使用 MVVM,但这是一个独立的应用程序,具有四个不同的窗口,可以相互切换。

标签: wpf mvvm


【解决方案1】:

我创建了一个“窗口加载器”类,应用程序类会在应用程序启动时对其进行实例化。窗口加载器有一个字典,它维护视图模型类型和视图类型的关联。它还有一个获取视图模型实例的方法,根据视图模型的类型解析视图,实例化视图,将视图的数据上下文设置为视图模型,然后显示它。窗口加载器还会在视图模型中注册一个事件,该事件在窗口想要关闭时引发。

窗口加载器实现了一个 IWindowLoader 接口,并且对它的引用保存在每个视图模型中(当窗口加载器实例化视图模型时,它会将自己分配给视图模型中的公共 IWindowLoader 属性)。因此,任何视图模型都可以导致任何其他视图模型在不了解视图且不显示本身的情况下显示。此外,可以轻松地模拟窗口加载器进行测试。

当我经历了与现在相同的过程时,我发现了许多相同基本模式的示例。我刚刚结束了自己的滚动。

【讨论】:

  • 听起来很合理。我得到了关闭窗口的事件。您是如何拨打电话以打开其中一种已注册类型的新窗口的?也是窗口加载器上的一个事件?您是否将类型作为字符串打开并让窗口加载器将其解析为类型?
  • 打开一个新窗口:每个视图模型都有一个 IWindowLoader 属性。并且每个视图模型(甚至是主窗口)都由应用程序类中的窗口加载器实例化。所以当窗口加载器创建视图模型时,它只是执行 viewModel.WindowLoader = this。然后 viewModel1 可以这样做: ViewModel2 viewModel = new ViewModel2(); this.WindowLoader.Show(viewModel);然后窗口加载器 Show 方法在字典中查找 typeof(viewModel) 并使用 Activator 实例化视图,将两者结合在一起,注册关闭事件并执行 window.Show()。
  • 小修正:窗口加载器查找 viewModel.GetType(),而不是 typeof(viewModel)。此外,与我原来的答案相反,我的窗口加载器 Show 方法不采用要显示的视图模型的类型,而是它的一个实例。这样做的原因是我喜欢让我的“父”视图模型实例化它们自己的子视图,以便它们可以在传递给窗口加载器之前设置属性并根据需要进行任何其他准备。
  • 嗯,其实我几乎明白了。 WindowLoader 中的 CloseWindow 事件将什么作为参数?我不知道如何获取对窗口实例的引用以关闭回 WindowLoader,除非它应该以某种方式保留所有打开窗口的副本?
  • 窗口加载器不维护对打开窗口的引用。相反,它在显示窗口之前将委托添加到视图模型实例中的 EventHandler。看起来像这样: viewModel.RequestClose += delegate(object sender, EventArgs e) { window.Close(); };
【解决方案2】:

解决此问题的一种方法是引入负责应用程序工作流的Controllers。他们在应用程序中创建、显示和关闭多个视图。

WPF Application Framework (WAF) 项目的示例应用程序中可以看到它是如何工作的。

【讨论】:

  • 由于其他原因,我不得不废弃窗口加载器,实际上最终编写了一个静态控制器类,如果我的任何视图模型想要在用户控制导航更改时执行某些操作,都可以订阅该类.我的主窗口通过将单个用户控件的可见性绑定到 DataTrigger 中的 CurrentNavigation 属性来执行实际切换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多