与从XAML创建的视图模型相关的问题

本文关键字:问题 模型 视图 XAML 创建 与从 | 更新日期: 2023-09-27 17:53:58

正如标题所暗示的,这个问题是专门寻找解决方案(或方法来避免)我在一个应用程序中遇到的问题,该应用程序直接从XAML创建视图模型(没有代码引用对象)。

这是一个成熟的,功能齐全的MVVM应用程序-在各个领域的视觉对象通常添加到主XAML窗口的部分,或弹出窗口,像这样:

<viewModels:MyViewModel MyDependencyProperty="{Binding}" />

在这些情况下,ViewModel的实例是用无参数构造创建的,我们有时会如上所示初始化依赖属性。

主XAML窗口有一个主视图模型的DataContext——ApplicationViewModel。大多数情况下,我们所有的视图都是带有样式的资源字典,为视图模型目标类型定义了各种模板。这些将被拉入皮肤XAML文件中的合并字典中。

问题1

有时候,应用程序周围的其他对象需要与ApplicationViewModel进行交互。然而,在实例化点,在XAML或其他地方没有可用的引用—导致过度使用静态ApplicationViewModel实例(不好)。

问题2

通常我们的xml实例化对象会有事件挂钩和可视化元素,需要显式解挂钩/处理。我们的可视化树非常庞大和复杂,因为我们的代码中没有任何对视图模型的引用,所以管理处理和避免内存增长的开销是一个持续的挑战——扔掉主窗口以及任何视图模型或可视化元素,这可能会导致它留在内存中。

我在这里不要求任何代码,更多的是你对这些问题的方法/经验的描述。

由于各种原因我不能提供代码——主要的一个原因是需要演示的东西太多了!

更新

仅供参考,关于该应用程序的另一件重要的事情是不断创建新的ViewModel项目,这些项目代表丰富的项目,这些项目出现在许多不断滚动的列表中,这些列表在选项卡中可用。在这些列表中,有许多命令操作、弹出式对话框和其他功能需要下游的ViewModel创建(目前是按需的)。这些列表支持各种触摸手势,包括轻弹/滚动、滑出菜单、触摸扩展和拖放,更不用说包含矢量图像和动画的丰富显示了!

与从XAML创建的视图模型相关的问题

我做过一些听起来很复杂的事情,我可以提供一些建议,使您的应用程序快速,响应迅速,内存高效:

  • 如果你想要快速的应用程序性能,并且在第三方组件中较少出现模糊的bug,请使用隐藏/显示而不是创建/销毁视觉树。这将大大加快速度。创建可视树是一个非常占用CPU的过程,所以尽量隐藏它并在需要时显示它,而不是在需要时创建它然后销毁它。如果某些东西崩溃了,WPF运行时非常非常擅长忽略与之相关的任何更新,因此它使用的CPU时间可以忽略不计。这可能会导致您创建大量的XAML块来控制可见XAML的许多子块的可见性,并且还将导致快速的应用程序性能。我们倾向于使用datatemplate来保持一切模块化,这样复杂性是可管理的。
  • 在应用程序启动时使用依赖注入(DI)来创建尽可能多的viewmodel。这意味着ViewModels之间的所有依赖关系都会自动为您解决。这意味着视图的可视树只创建一次,然后隐藏,匹配的ViewModel只创建一次,然后不再创建。所有的Model类都只创建一次,然后永远不会被丢弃或再次创建。我推荐Unity,但是任何形式的DI都可以。避免使用MEF作为你的主要DI机制,因为Unity更适合这个任务。有时候自动创建类是不可避免的(比如当第三方组件在用户向列表中添加内容时自动创建新的ViewModel类),但通常这些类都很小,所以这不会影响性能。我不建议使用事件钩子。这将导致viewmodel之间的耦合过多。相反,使用响应式扩展(Reactive Extensions, RX)在viewmodel之间传递事件。有一个具有主题的公共类。一个ViewModel可以使用OnNext发送事件,而另一个ViewModel可以使用Subscribe接收事件。然而,这只能作为最后的手段:尝试构造对象层次结构,这样ViewModels就可以相互引用,而不必诉诸事件传递。
  • 最后,使用async/await你可以转移处理主GUI线程(我相信你已经这样做了)。