在上图中,child是ContentPresenter。它的内容是一个ViewModel。但是,它的ContentTemplate为空。
在我的XAML中,我有一个具有以下结构的TabControl:
<local:SuperTabControlEx DataContext="{Binding WorkSpaceListViewModel}"
x:Name="superTabControl1" CloseButtonVisibility="Visible" TabStyle="OneNote2007" ClipToBounds="False" ContentInnerBorderBrush="Red" FontSize="24" >
<local:SuperTabControlEx.ItemsSource>
<Binding Path="WorkSpaceViewModels" />
</local:SuperTabControlEx.ItemsSource>
<TabControl.Template>
<ControlTemplate
TargetType="TabControl">
<DockPanel>
<TabPanel
DockPanel.Dock="Top"
IsItemsHost="True" />
<Grid
DockPanel.Dock="Bottom"
x:Name="PART_ItemsHolder" />
</DockPanel>
<!-- no content presenter -->
</ControlTemplate>
</TabControl.Template>
<TabControl.Resources>
<DataTemplate DataType="{x:Type vm:WorkSpaceViewModel}">
....
WorkSpaceViewModels是WorkSpaceViewModel的ObservableCollection。此代码使用Keeping the WPF Tab Control from destroying its children中的代码和技术。
上面显示的TabControl.Resource中的正确DataTemplate似乎是为两个Tabs呈现我的ViewModel。
但是,我的基本问题是,我的视图如何与我的WorkSpaceViewModel相连,但ContentPresenter上的ContentTemplate是否为空?我的要求是从ViewModel访问可视组件,因为在某些用户操作时,视图的设置将从ViewModel中的属性解除绑定,我需要重新绑定它。
答案 0 :(得分:1)
DataTemplate是“隐式”定义的。 ContentPresenter将首先使用它的ContentTemplate / Selector(如果有的话)。如果没有,那么它将搜索没有显式x:Key且其DataType与其内容类型匹配的DataTemplate资源。
View Model不应该真正了解它的相关View。听起来你的Bindings有问题,因为一般来说你不应该“重新绑定”它们。无论哪种方式,attached behavior都是实现这一目标的好方法。
答案 1 :(得分:0)
我认为这个问题的完整答案需要DrWPF的完整系列ItemsControl: A to Z。但是,我相信当DataTemplate被“膨胀”以显示它已被框架链接到的数据项时,要点就在于存储视觉元素的位置。
在“ItemsControl:'L'用于Lookless”的Introduction to Control Templates部分中,DrWPF解释说“我们已经知道DataTemplate用于声明出现在数据项中的数据项的可视化表示。应用程序的逻辑树。在'P'用于Panel时,我们了解到ItemsPanelTemplate用于声明ItemsControl中使用的项目主机。“
对于我的问题,我仍然没有成功导航可视化树以获得对我的拆分器项的引用。到目前为止,这是我最好的尝试:
// w1 is a Window
SuperTabControlEx stc = w1.FindName("superTabControl1") as SuperTabControlEx;
//SuperTabItem sti = (SuperTabItem)(stc.ItemContainerGenerator.ContainerFromItem(stc.Items.CurrentItem));
ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(stc);
//ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(sti);
DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
上述代码试图实现on the msdn web site所示的技术。但是,当我将它应用于我的代码时,一切看起来都不错,除了myDataTemplate返回null。如您所见,我在SuperTabControlEx和SuperTabItem上尝试了相同的技术,分别派生自TabControl和TabItem。正如我在原始帖子中所描述的那样,在XAML片段中,SuperTabControlEx也实现了Keeping the WPF Tab Control from destroying its children的代码。
此时,或许最重要的是,我认为这是导航Visual Tree的练习。我将修改问题的标题,以反映我对该问题的新概念。