我有一个实体类。该实体具有许多属性,并且实体的数据在TabItems
的多个TabControl
中向用户显示。我还实现了MVVM方法。
当首先向用户显示屏幕时,我想仅绑定活动标签页控件,并且当用户浏览标签页时,将根据需要产生额外的单独绑定。我怎样才能做到这一点?
答案 0 :(得分:16)
你没有任何事可做,这是默认行为。在选择DataTemplate
之前,TabItem
内容的TabItem
将不会被实例化
<Window.Resources>
<DataTemplate DataType="{x:Type vm:Page1ViewModel}">
<v:Page1View />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:Page3ViewModel}">
<v:Page3View />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:Page3ViewModel}">
<v:Page3View />
</DataTemplate>
</Window.Resources>
...
<TabControl ItemsSource="{Binding Pages}"
DisplayMemberPath="Title">
</TabControl>
在上面的代码中,TabControl
会根据项目类型选择适当的DataTemplate
,并且仅在选择该项目时才会呈现它。
编辑2:显然你想在几个页面上显示单个ViewModel的数据。如果您希望懒惰地实例化每个TabItem
的控件,则需要使用每个ContentTemplate
的{{1}}属性:
TabItem
答案 1 :(得分:1)
我创建了这个适用于我们第三方tabcontrol的解决方案。
想法是在设置时“拦截”datacontext,将其保存以供日后使用,并将datacontext设置为null。当tabitem获得焦点时,我们然后设置datacontext,数据将填充在选项卡中。
作为依赖属性实现。然后只需在需要的选项卡上设置属性(不要在默认情况下出现的选项卡上设置它)
#region SavedDataContext
private static object GetSavedDataContext(TabItemEx tabItem)
{
return tabItem.GetValue(SavedDataContextProperty);
}
private static void SetSavedDataContext(TabItemEx tabItem, object value)
{
tabItem.SetValue(SavedDataContextProperty, value);
}
public static readonly DependencyProperty SavedDataContextProperty =
DependencyProperty.RegisterAttached("SavedDataContext", typeof(object),
typeof(Attach), new UIPropertyMetadata(null));
#endregion
#region LazyLoad
public static bool GetLazyLoad(TabItemEx tabItem)
{
return (bool)tabItem.GetValue(LazyLoadProperty);
}
public static void SetLazyLoad(TabItemEx tabItem, bool value)
{
tabItem.SetValue(LazyLoadProperty, value);
}
private static readonly DependencyProperty LazyLoadProperty =
DependencyProperty.RegisterAttached("LazyLoad", typeof(bool),
typeof(Attach), new UIPropertyMetadata(false, LazyLoadPropertyChanged));
private static void LazyLoadPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs eventArgs)
{
if ((bool)eventArgs.NewValue)
{
var tabItemEx = sender as TabItemEx;
if (tabItemEx == null)
return;
tabItemEx.DataContextChanged += DataContextChanged;
tabItemEx.GotFocus += TabGotFocus;
}
}
#endregion
private static void TabGotFocus(object sender, RoutedEventArgs e)
{
var tabItemEx = sender as TabItemEx;
if (tabItemEx == null)
return;
tabItemEx.GotFocus -= TabGotFocus;
tabItemEx.DataContext = GetSavedDataContext(tabItemEx);
tabItemEx.IsSelected = true;
}
private static void DataContextChanged(object sender, DependencyPropertyChangedEventArgs eventArgs)
{
var tabItemEx = sender as TabItemEx;
if (tabItemEx == null)
return;
SetSavedDataContext(tabItemEx, eventArgs.NewValue);
tabItemEx.DataContextChanged -= DataContextChanged;
tabItemEx.DataContext = null;
}
答案 2 :(得分:1)
标记为答案方法有一个缺点 - TabItem的内容在选择时将始终重新呈现。如果它很重要 - 您可以尝试this。