使用MVVM实现DataTemplate驱动的视图注入

5
我有一个容器视图,大致长这样:
<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更改时重新绑定视图模型。我理解这种行为正确吗?这是一种首选做法吗?我如何验证在切换视图时没有浪费内存?

2个回答

2
为了进一步解释Pavel的回答并澄清当您更改视图模型时视图会发生什么,新的视图将为新的视图模型生成,并且旧的视图将会在时间允许的情况下被垃圾回收。
问题在于有时我们会有一些在代码后台(非弱事件)注册到某些事件的视图,这将阻止视图被回收,从而导致内存泄漏。
两种方法:
1.任何视图代码后台中的事件订阅应该是弱化的(PRISM中的EventAggregator),以允许垃圾回收。
2.向Unity容器注册视图实例,并在需要重用它时解析它。在将其注入区域之前,只需更新DataContext即可。
希望这可以帮助你。

1

每次使用视图模型都会实例化一个新的MyView。如果要重用用户控件,可以在每个用户控件上设置DataContext属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接