【问题标题】:WPF MVVM: How to load views "on demand" without using plug-in architecture?WPF MVVM:如何在不使用插件架构的情况下“按需”加载视图?
【发布时间】:2011-10-12 06:04:43
【问题描述】:

我有一个类似于 Outlook 的 WPF UI,左侧是导航,顶部是工具栏,底部是状态栏,所有这些都在 DockPanel 中。

应用程序的“主要”区域位于 DataGrid 内,即 LastChild,因此填充了剩余空间,目前看起来像这样:

<Grid DockPanel.Dock="Right">
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition />
    </Grid.RowDefinitions>
    <views:View1 Grid.Column="0" Grid.Row="0"/>
    <views:View2 Grid.Column="0" Grid.Row="0"/>
    <views:View3 Grid.Column="0" Grid.Row="0"/>
    <views:View4 Grid.Column="0" Grid.Row="0"/>
</Grid>

这些视图都是具有自己的 ViewModel 的用户控件,其中 Visibility 属性绑定到其 ViewModel 中的属性并由导航窗格选择控制。 When a navigation pane item is selected the main ViewModel sends a message to ViewModels of the views and upon receiving the message the ViewModels of the views set their Visibility properties accordingly...

现在,这工作正常,但感觉不对,因为这些视图的所有 ViewModel 都是在应用启动时实例化的,而不是在选择相关导航窗格时提出有关性能和内存使用的问题...

My question is if there is a way of loading each view and its ViewModel "on demand", when the related navigation pane is selected and unloading these views and ViewModels when a different navigation pane is selected without resorting to PRISM/MEF or其他一些插件架构...更一般地说,您将如何构建这样一个在主视图中“嵌入”多个视图/ViewModel 的应用程序?

【问题讨论】:

    标签: wpf mvvm


    【解决方案1】:

    这是我的工作:

    首先,在您的主 ViewModel(服务于主窗口的那个)上,添加一个 Content 属性:

    object _content;
    public object Content
    {
        get { return _content; }
        set
        {
            _content = value;
            RaisePropertyChanged("Content");
        }
    }
    

    当用户从一个视图切换到另一个视图时,将Content 属性设置为他们选择的视图的适当视图模型。

    然后,您可以在主窗口中使用 ContentControl 显示当前的 Content ViewModel:

    <ContentControl Content="{Binding Content}" />
    

    ...在此之上,为Content 可能设置为的各种 ViewModel 中的每一个定义一个 DataTemplate:

    <DataTemplate DataType="{x:Type vm:FooViewModel}">
        <my:FooUserControl />
    </DataTemplate>
    
    <DataTemplate DataType="{x:Type vm:BarViewModel}">
        <my:BarUserControl />
    </DataTemplate>
    

    因此,现在 ContentControl 将负责根据当前“活动”的 ViewModel 来初始化和显示您的每个 UserControl。

    【讨论】:

    • 您可能还对我的 MVVM Light contrib 项目感兴趣,其中包括一个 ScreenConductor 类:matthamilton.net/madprops-mvvmlight-screenconductor
    • 还可以查看 Caliburn Micro,尤其是屏幕和导体。
    • @Derek 同意 - 我是 MVVM Light 人,但 CM 为你做了很多。
    • @kzen 如果您想要一个使用此技术的完整“示例”应用程序,请查看bitbucket.org/mabster/comicster
    • 看来还有一个问题...当Content 设置为另一个ViewModel 时,以前的ViewModel 不会超出范围,它会保留在内存中...知道如何处理它是因为 Content = null 在分配新的 ViewModel 之前不起作用?
    猜你喜欢
    • 2020-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    • 2020-11-28
    相关资源
    最近更新 更多