如何从ContentTemplate绑定到周围的自定义控件?

时间:2008-09-29 13:46:16

标签: wpf xaml binding datatemplate

我有以下用户控件:

<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的{​​{1}}内绑定到此属性和其他属性。但由于奇怪的互动,DataTemplate中的TextBlock绑定到DataTemplate父容器,也被称为“自我”,但已定义在另一个Xaml文件中。

问题

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

我已经尝试了什么

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

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

修改

与此同时,我发现问题是:如果ControlTemplate包含{TabControl,则ItemsTemplate不能拥有(任何)DisplayMemberPath(包括ItemsSource) {1}}秒。有a thread on MSDN Forum explaining why

由于这似乎是WPF的TabControl的一个基本问题,我正在关闭这个问题。谢谢你的帮助!

2 个答案:

答案 0 :(得分: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>

如果它不起作用,请尝试在&lt; TabItem /&gt;中粘贴此属性:

DataContext="{Binding RelativeSource={RelativeSource self}}"

答案 1 :(得分:1)

似乎问题在于您在没有实际使用内容属性的情况下使用ContentTemplate。 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>