Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 使用MVVM的数据模板驱动的视图注入_Wpf_Mvvm_Memory Management_Datatemplate_Instantiation - Fatal编程技术网

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

Wpf 使用MVVM的数据模板驱动的视图注入,wpf,mvvm,memory-management,datatemplate,instantiation,Wpf,Mvvm,Memory Management,Datatemplate,Instantiation,我有一个容器视图,看起来像这样 <UserControl x:Class="Views.ContainerView"> <UserControl.Resources> <ResourceDictionary> <DataTemplate DataType="{x:Type viewmodels:AViewModel}"> <views:MyView />

我有一个容器视图,看起来像这样

<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。我对这种行为的理解正确吗?这是首选做法吗?在视图之间切换时,如何验证我没有搅动内存?

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

要扩展Pavel的回答,并澄清当您更改视图模型时视图会发生什么情况,将为新视图模型生成新视图,旧视图有望及时被垃圾回收

这样做的问题是,有时我们会有一些视图注册到代码隐藏中的某个事件(非弱事件),这将阻止收集该视图,并且将发生内存泄漏

两种方法

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