7

我有以下用户控制:

<TabItem 
    x:Name="Self"
    x:Class="App.MyTabItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:app="clr-namespace:App"
    >
    <TabItem.Header>
        <!-- This works -->
        <TextBlock Text="{Binding ElementName=Self, Path=ShortLabel, UpdateSourceTrigger=PropertyChanged}"/>
    </TabItem.Header>
    <TabItem.ContentTemplate>
        <DataTemplate>
            <!-- This binds to "Self" in the surrounding window's namespace -->
            <TextBlock Text="{Binding ElementName=Self, Path=ShortLabel, UpdateSourceTrigger=PropertyChanged}"/>

这个自定义的 TabItem 定义了一个DependencyProperty“ShortLabel”来实现一个接口。我想从TabItem's中绑定到 this 和其他属性DataTemplate。但是由于奇怪的交互,其中TextBlockDataTemplate被绑定到 的父容器,该容器TabItem也称为“Self”,但在另一个 Xaml 文件中定义。

问题

为什么绑定在 TabItem.Header 中起作用,但在 TabItem.ContentTemplate 中不起作用,我应该如何继续从 DataTemplate 中获取用户控件的属性?

我已经尝试过的

  • TemplateBinding: 尝试在TabItem.
  • FindAncestor, AncestorType={x:Type TabItem}: 找不到TabItem父母。MyTabItem当我指定类型时,这也不起作用。
  • ElementName=Self: 尝试绑定到错误范围内具有该名称的控件(父容器,而不是TabItem)。我认为这给出了一个提示,为什么这不起作用:DataTemplate 不是在 XAML 中定义的位置创建的,而是显然是由父容器创建的。

我假设我可以替换整个ControlTemplate来实现我正在寻找的效果,但是由于我想保留默认外观TabItem而不必维护整体ControlTemplate,所以我非常不愿意这样做。

编辑

同时我发现问题是:如果包含s,则TabControls 不能有(任何)ItemsTemplate(包括) 。MSDN 论坛上有一个帖子解释了原因。DisplayMemberPathItemsSourceVisual

由于这似乎是 WPF 的 TabControl 的一个基本问题,所以我要结束这个问题。感谢你的帮助!

4

2 回答 2

2

问题似乎是您使用的是 ContentTemplate 而没有实际使用 content 属性。ContentTemplate 的DataTemplate 的默认DataContext 是TabItem 的Content 属性。但是,我所说的都没有真正解释为什么绑定不起作用。不幸的是,我不能给你一个明确的答案,但我最好的猜测是,这是因为 TabControl 重用了 ContentPresenter 来显示所有选项卡项的内容属性。

因此,在您的情况下,我会将代码更改为如下所示:

<TabItem
    x:Class="App.MyTabItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:app="clr-namespace:App"
    Header="{Binding ShortLabel, RelativeSource={RelativeSource Self}}"
    Content="{Binding ShortLabel, RelativeSource={RelativeSource Self}}" />

如果 ShortLabel 是一个更复杂的对象而不仅仅是一个字符串,那么你会想要引入一个 ContentTemplate:

<TabItem
    x:Class="App.MyTabItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:app="clr-namespace:App"
    Header="{Binding ShortLabel, RelativeSource={RelativeSource Self}}"
    Content="{Binding ComplexShortLabel, RelativeSource={RelativeSource Self}}">
    <TabItem.ContentTemplate>
        <DataTemplate TargetType="{x:Type ComplexType}">
            <TextBlock Text="{Binding Property}" />
        </DataTemplate>
    </TabItem.ContentTemplate>
</TabItem>
于 2008-11-01T06:48:29.307 回答
1

尝试这个。我不确定它是否会起作用,但是

<TabItem 
    x:Name="Self"
    x:Class="App.MyTabItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:app="clr-namespace:App"
    >
    <TabItem.ContentTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=ShortLabel}"/>
        </DataTemplate>
    </TabItem.ContentTemplate>
</TabItem>

如果它不起作用,请尝试将此属性粘贴在 <TabItem/> 中:

DataContext="{Binding RelativeSource={RelativeSource self}}"
于 2008-10-08T19:58:57.500 回答