代码之家  ›  专栏  ›  技术社区  ›  kenwarner

使用MVVM的数据模板驱动的视图注入

  •  5
  • kenwarner  · 技术社区  · 15 年前

    我有一个像这样的容器视图

    <UserControl x:Class="Views.ContainerView">
        <UserControl.Resources>
            <ResourceDictionary>
                <DataTemplate DataType="{x:Type viewmodels:AViewModel}">
                    <views:MyView />
                </DataTemplate>
                <DataTemplate DataType="{x:Type viewmodels:BViewModel}">
                    <views:MyView />
                </DataTemplate>
                <DataTemplate DataType="{x:Type viewmodels:CViewModel}">
                    <views:MyView />
                </DataTemplate>
                <DataTemplate DataType="{x:Type viewmodels:DViewModel}">
                    <views:MyView />
                </DataTemplate>
            </ResourceDictionary>
        </UserControl.Resources>
        <Grid>
            <ListBox ItemsSource="{Binding Path=AvailableViewModels}" 
                SelectedItem="{Binding Path=CurrentViewModel}" 
                IsSynchronizedWithCurrentItem="True" />
            <ContentControl Content="{Binding Path=CurrentViewModel}" />
        </Grid>
    </UserControl>
    

    我的所有视图模型都继承了BaseViewModel,所以我将视图转换为

    <UserControl x:Class="Views.ContainerView">
        <UserControl.Resources>
            <ResourceDictionary>
                <DataTemplate DataType="{x:Type viewmodels:BaseViewModel}">
                    <views:MyView />
                </DataTemplate>
            </ResourceDictionary>
        </UserControl.Resources>
        <StackPanel>
            <ListBox ItemsSource="{Binding Path=AvailableViewModels}" 
                SelectedItem="{Binding Path=CurrentViewModel}" 
                IsSynchronizedWithCurrentItem="True" />
            <ContentControl Content="{Binding Path=CurrentViewModel}" />
        </StackPanel>
    </UserControl>
    

    认为它只会实例化一个MyView,并在ListBox.SelectedItem更改时重新绑定ViewModel。我是否正确理解这种行为?这是首选做法吗?当我在视图之间切换时,如何验证我没有搅乱内存?

    2 回复  |  直到 14 年前
        1
  •  1
  •   Pavel    15 年前

    它将为您使用的每个视图模型实例化一个新的myview。如果要重用用户控件,可以对每个用户控件设置DataContext属性。

        2
  •  2
  •   Tri Q Tran    14 年前

    扩展pavel的答案并澄清当您更改视图模型时,视图会发生什么情况,是将为新视图模型生成新视图,而旧视图将 有希望地 及时收集垃圾。

    这方面的问题是,有时我们会有一些视图注册到代码隐藏中的某个事件(非弱事件),这将阻止收集视图,而您 内存泄漏。

    两种方法。

    1. 视图代码中的任何事件订阅都应该减弱(prism中的eventaggregator),以允许垃圾收集。
    2. 用Unity容器注册一个视图实例,并在需要重用它时解析它。在将其注入区域之前,只需更新DataContext。

    希望这有帮助。