wpf - View 分层且需要换入换出时定位 ViewModel 的策略

标签 wpf silverlight mvvm mvvm-light simple-mvvm

假设我正在为汽车构建导航系统:

  • 主窗口将包含一个屏幕、模式按钮和一个音量控制。
  • 根据系统的模式,屏幕将显示音频、气候或导航面板。
  • 在音频模式下,会有另一组模式按钮和一个面板,可以显示 radio 、CD 或 MP3 控件。

  • 过去,我对此类安排的策略是让我的 View 模型遵循与 View 完全相同的层次结构。所以:
  • MainViewModel 将有一个 ScreenViewModel。
  • ScreenViewModel 将具有 AudioViewModel、ClimateViewModel 和 NavigationViewModel。它还有一个 CurrentViewModel 属性,可以设置为音频、气候或导航 View 模型,具体取决于系统模式。
  • AudioViewModel 类似于 ScreenViewModel,为每个音频系统的模式( radio 、CD 和 MP3)保存 View 模型以及用于存储当前模式的 View 模型的属性。

  • 用于将 View 绑定(bind)到 View 模型的 XAML 如下所示:
    <Window.Resources>
        <DataTemplate DataType="{x:Type vm:AudioViewModel}">
            <view:AudioPanel />
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm:ClimateViewModel}">
            <view:ClimatePanel />
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm:NavigationViewModel}">
            <view:NavigationPanel />
        </DataTemplate>
    </Window.Resources>
    
    <ContentControl Content="{Binding CurrentViewModel}" />
    

    如果用户正在收听广播并决定在导航系统中输入目的地,他们将单击导航模式按钮。 MainWindowViewModel 上会有一个命令将系统模式更改为“导航”并将 CurrentViewModel 设置为 NavigationViewModel。这将导致 NavigationView 被交换。非常干净的解决方案。

    不幸的是,虽然以这种方式在执行模式下运行良好,但在尝试使用 Expression Blend 中的从属 View (例如 AudioPanel)时它会崩溃,因为父 View 模型 (MainWindowViewModel) 不存在以提供 AudioViewModel。

    似乎在 MVVM Light 和 Simple MVVM 等工具包中支持的解决方案是使用 ViewModelLocator,然后通过绑定(bind)到定位器上的正确属性让 View 设置它自己的 DataContext。然后定位器提供 View 模型的一个实例。

    “ViewModelLocator 做事方式”解决了“可设计性”问题,但我不清楚如何表示层次关系并处理一个 View 与另一个 View 的交换。从概念上讲,让 View 模型保存 subview 模型对我来说更有意义。它正确地表示了 View 的层次结构, View 的交换很容易,如果不再需要 View ,则只需删除对父 View 的引用,关联的 View 模型及其所有下属都将被垃圾收集。

    问题

    构建 ViewModelLocator 以处理分层 View 、基于系统模式交换 View 和删除 View 的最佳实践是什么?

    具体来说:
  • 您如何组织 View 模型以便清楚地表示层次关系?
  • 您如何处理将一个现有 View 换成另一个 View (例如用导航面板替换音频面板)?
  • 当不再需要关联的父 View 时,如何确保释放父 View 模型和 subview 模型以进行垃圾回收?
  • 最佳答案

    看起来 View 层次结构中的当前 View 是 View “状态”的一部分,因此它将具有自己的“模型”( View 模型)实体来管理这种关系。我不会为此使用 IoC 容器,但我会使用它来注册“ View 管理器”用来创建“ subview ”的工厂。

    关于wpf - View 分层且需要换入换出时定位 ViewModel 的策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7560765/

    相关文章:

    c# - 转换为字节数组并插入到其他数组中

    c# - 如何在 silverlight 客户端对象模型中设置 SharePoint "Author"?

    wpf - Silverlight/WPF 和 Blend : DataBind a text field, 但定义设计时值?

    silverlight - Com Interop 问题 Silverlight 4 和 MS Access 2010

    c# - 将 UserControl 加载到 ComboBox 更改时的窗口区域

    c# - 在 wpf 中处理点击序列的最佳方法

    c# - MVVM - 单击按钮时在哪里调用函数?

    asp.net-mvc - 无法对 Azure AD 安全 MVC Web 应用程序的 native 客户端进行身份验证

    c# - 无法绑定(bind)依赖属性

    c# - 与 ValidatesOnException 绑定(bind)会在 .Net4 中引发未处理错误