与从XAML

时间:2015-06-07 22:14:07

标签: c# wpf xaml mvvm

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

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

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

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

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

问题1

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

问题2

我们的XAML实例化对象通常会有事件挂钩和可视元素,需要显式取消/处理。我们的可视树非常庞大和复杂,因为我们的视图模型中没有任何代码参考,所以管理处理和避免内存增长会产生持续的开销 - 并且抛弃主窗口以及任何视图模型或可能导致其留在记忆中的视觉元素 - 是一个持续的挑战。

我不是在这里要求任何代码,更多是为了描述您对这些问题的处理方法。

由于各种原因,我无法提供代码 - 主要原因是需要进行大量演示!

更新

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

1 个答案:

答案 0 :(得分:1)

在完成类似复杂事情的工作之后,我可以提供一些建议,使您的应用程序快速,响应和内存效率:

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