【发布时间】:2016-07-08 17:33:04
【问题描述】:
我知道,这个topic 已经是discussed 很多times,所以直截了当。
这是TabControl的ItemsSource:
Tabs = new ObservableCollection<aTabViewModel>
{
new HomeViewModel(),
new StatisticsViewModel()
};
这是TabControl 本身
<TabControl ItemsSource="{Binding Tabs}">
<TabControl.Resources>
<DataTemplate DataType="{x:Type pagesVM:HomeViewModel}">
<pages:Home/>
</DataTemplate>
<DataTemplate DataType="{x:Type pagesVM:StatisticsViewModel}">
<pages:Statistics/>
</DataTemplate>
</TabControl.Resources>
<TabControl.ItemContainerStyle>
<Style BasedOn="{StaticResource MetroTabItem}" TargetType="TabItem">
<Setter Property="Header" Value="{Binding Header}" />
</Style>
</TabControl.ItemContainerStyle>
HomeViewModel 和StatisticsViewModel 第一次在我们将它们添加到Tabs 集合时被实例化,第二次在我们在应用程序中选择选项卡时被实例化(这似乎是TabControl 的行为)。而且这种双重加载显然是不对的。
问:我怎样才能让我的标签只在被选中时才加载?
【问题讨论】:
-
我认为虚拟机不会被多次实例化。
-
使 TabControl 列表的 ItemsSource
保存选项卡标题,在 ViewModel 中添加字符串属性以保存所选选项卡,在 SelectedTab 的设置器中检查新选择并创建其 DataContext 如果选项卡已加载,因此只需分配它。 -
很确定您对视图模型和视图感到困惑,通过选项卡控件在此处执行的任何操作来创建虚拟机是相当不可能的。
-
@StanleyRussian 他是对的,TabControls 不会自己做这一切。也就是说,一个解决方案是在创建视图模型时不让视图模型加载任何数据。相反,它们实现了一个接口 ILazyLoad,该接口具有一个 LazyLoad() 方法,该方法加载虚拟机的 if 内容,它尚未加载。然后在 TabControl_SelectionChanged 的代码隐藏中,获取新选项卡的 DataContext,如果它实现了 ILazyLoad,则进行强制转换和调用。
标签: c# wpf mvvm tabs lazy-loading