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 更改时重新绑定视图模型。我是否正确理解了这种行为?这是首选做法吗?当我在视图之间切换时,如何验证我没有搅动内存?

4

2 回答 2

2

为了扩展 Pavel 的答案并澄清当您更改视图模型时视图会发生什么,将为新视图模型生成一个新视图,并且希望旧视图及时被垃圾收集。

这样做的问题是有时我们会有视图注册到代码后面的某些事件(非弱事件),这将阻止视图被收集,并且您有内存泄漏。

两种方法。

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

希望这可以帮助。

于 2010-11-11T00:51:33.083 回答
1

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

于 2009-10-21T03:09:03.253 回答