WPF:TabControl &数据模板

发布于 2024-09-29 16:22:23 字数 1457 浏览 3 评论 0原文

我只是想了解以下场景。我在哪里实现绑定到 ObservableCollection

无数据模板

当我没有任何DataTemplate 中,文本 WpfApplication1.TabViewModel 出现在选项卡标题和内容中。好吧,我明白这部分了。

Just ItemTemplate

当我刚刚完成时

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

,我的选项卡标题已填充。选项卡内容仍然是 WpfApplication1.TabViewModel

只是 DataTemplate

当我的 中只有以下内容时,

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

该模板会填充选项卡标题。

两者

当我两者都有时,ItemTemplate 填充选项卡标题,而 DataTemplate 填充选项卡内容。为什么会有这样的差异。 ItemTemplate &如果另一个不存在,DataTemplate 会填充选项卡标题。如果两者都存在,则 ItemTemplate 填充标题,而 DataTemplate 填充内容。

虽然我有工作,但我很困惑。难道不应该像 那样填充标题,而 填充内容吗?

I just want to understand the following scenario. Where I am implementing a <TabControl> bound to a ObservableCollection<TabViewModel>

No Data Templates

When I don't have any DataTemplates, the text WpfApplication1.TabViewModel appears in the Tab Header and Content. Ok I understand this part.

Just ItemTemplate

When I just have

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

Then my tab header is filled. The tab content is still WpfApplication1.TabViewModel.

Just DataTemplate

When I just have the below in my <Window.Resources>

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

That templates fills up the tab header.

Both

When I have both, the ItemTemplate fills up the Tab Header while the DataTemplate fills up the tab content. Why all this difference. ItemTemplate & DataTemplate fills up the tab header if the other is not present. If both are present, ItemTemplate fills up the header while DataTemplate fills the content.

Though I have things working, I am quite confused. Shouldn't something like <TabControl.HeaderTemplate> be what fills the header and <TabControl.ItemTemplate> fill up the content?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

乖不如嘢 2024-10-06 16:22:23

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

  • 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 会尝试沿着您的逻辑树查找合适的 DataTemplate。当它找到它时,它会使用它来渲染视图模型。如果找不到,它会调用 ToString 并呈现它。

因此,为了解决您的具体情况:

Just ItemTemplate

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

仅 DataTemplate

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

注意:您没有明确指出这就是您的问题中发生的情况。如果我错了请纠正我。

两者

在这种情况下,您已经明确说明了如何呈现选项卡标题,但没有呈现选项卡内容。因此,显式 DataTemplate 用于选项卡标题,隐式 DataTemplate 用于选项卡内容。

First of all, there are two templates involved here:

  • TabControl.ItemTemplate, used to render the TabItem headers
  • TabControl.ContentTemplate, used to render the TabItem contents

If you don't set these properties explicitly then WPF will attempt to resolve them elsewhere. It will walk up the logical tree looking for a resource telling it how to render your view model. If it finds a DataTemplate that has a matching DataType but no key, it will use it to render the view model. If it doesn't find one, it'll default to rendering the ToString value of the object.

So, if you want to be explicit, you want something like this:

<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>

Since you're not being specific, WPF is attempting to walk up your logical tree to find an appropriate DataTemplate. When it finds it, it uses it to render the view model. Where it doesn't find it, it calls ToString and renders that.

So to address your specific cases:

Just ItemTemplate

You've explicitly stated how to render tab headers but not tab contents. So the former is rendered using the provided DataTemplate, but the latter will default to ToString.

Just DataTemplate

You've not explicitly stated how to render either tab headers or tab contents. Therefore, WPF searches for an appropriate DataTemplate for both. Since both contain an instance of your view model (that's their DataContext) then the same DataTemplate will be used to render tab headers and their contents.

NOTE: you didn't explicitly state that this is what's happening in your question. Correct me if I'm wrong.

Both

In this case, you've explicitly stated how to render tab headers but not tab contents. Therefore, the explicit DataTemplate is used for tab headers and the implicit DataTemplate is used for tab contents.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文