WPF: TabControl和DataTemplates

36

我只是想了解以下情况。 我正在实现一个绑定到ObservableCollection<TabViewModel><TabControl>

没有数据模板

当我没有任何DataTemplate时,在选项卡标题和内容中出现文本WpfApplication1.TabViewModel。好的,我理解这部分。

只有

当我只有ItemTemplate时,头部显示的是创建TabViewModel时传递给构造函数的字符串参数的值,并且内容是空的。我不明白为什么会发生这种情况。

<TabControl.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding TabTitle}" />
        </StackPanel>
    </DataTemplate>
</TabControl.ItemTemplate>

然后我的标签标题已经填充。该标签内容仍为WpfApplication1.TabViewModel

只需要使用DataTemplate

当我在<Window.Resources>中只有以下内容时

<DataTemplate DataType="{x:Type local:TabViewModel}">
    <TextBox Text="{Binding Text}" />
</DataTemplate>

该模板填充选项卡标题。

两者

当我同时使用ItemTemplateDataTemplate时,ItemTemplate填充了选项卡头部,而DataTemplate填充了选项卡内容。为什么会出现这种差异呢?如果另一个不存在,ItemTemplateDataTemplate都会填充选项卡头部。如果两者都存在,则ItemTemplate填充选项卡头部,而DataTemplate填充内容。

虽然我已经让事情正常运作,但我还是很困惑。难道像<TabControl.HeaderTemplate>这样的东西不应该填充标题,而<TabControl.ItemTemplate>则填充内容吗?

1个回答

64

首先,这里涉及到两个模板:

  • TabControl.ItemTemplate, 用于呈现 TabItem 的标题
  • TabControl.ContentTemplate, 用于呈现 TabItem 的内容

如果您没有显式设置这些属性,则WPF会尝试在其他地方解决它们。它将沿着逻辑树向上查找资源,以告诉它如何呈现您的视图模型。如果找到一个具有匹配的DataType但没有键的DataTemplate,它将使用它来渲染视图模型。如果找不到,则默认呈现对象的ToString值。

因此,如果想要明确指定,您需要像这样:

<TabControl ItemsSource="{Binding Tabs}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding TabTitle}"/>
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Text}"/>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

由于您没有具体说明,WPF会尝试沿逻辑树向上查找适当的。找到后,它将使用它来呈现视图模型。如果找不到,则调用ToString并进行呈现。

所以针对您的特定情况:

仅ItemTemplate

您已明确说明如何呈现选项卡标题,但未说明如何呈现选项卡内容。因此前者使用提供的进行呈现,而后者将默认为ToString

仅DataTemplate

您未明确说明如何呈现选项卡标题或选项卡内容。因此,WPF会搜索适用于两者的适当的。由于两者都包含您的视图模型的实例(即它们的),因此将使用相同的来呈现选项卡标题和它们的内容。

注意:您在问题中没有明确说明这是正在发生的事情。如果我错了,请纠正我。

两者都有

在这种情况下,您已明确说明如何呈现选项卡标题,但未说明如何呈现选项卡内容。因此,明确的用于选项卡标题,而隐式的用于选项卡内容。


如果我想要一个带有内容的列表框和选项卡控件,该怎么做?选项卡项目源将拥有列表框的项目列表。列表框本身也有数据模板。 - Programmer
首先,这里涉及到两个模板... 啊!你会认为在DataTemplate之外指定TabItem的方式与在TabControl ItemTemplate属性中工作方式相同,因为ListView等也是这样工作的。谢谢! - user1454265

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接