How to associate with a ContentTemplate with an surrounding custom control?

I have the following user control:

<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 namespace --> <TextBlock Text="{Binding ElementName=Self, Path=ShortLabel, UpdateSourceTrigger=PropertyChanged}"/> 

This custom TabItem defines the DependencyProperty ShortLabel to implement the interface. I would like to bind to this and other properties from the TabItem DataTemplate . But due to weird interactions, the TextBlock inside the DataTemplate bound to the parent TabItem container , which is also called β€œI”, but defined in another Xaml file.

Question

Why does binding work in TabItem.Header but not from inside TabItem.ContentTemplate, and how do I get to user control properties from a DataTemplate?

What have i tried

  • TemplateBinding : Attempts to bind to ContentPresenter inside the gut TabItem .
  • FindAncestor, AncestorType={x:Type TabItem} : The TabItem parent was not found. This also does not work when I specify the type MyTabItem .
  • ElementName=Self : ElementName=Self to associate a control with this name in the wrong scope (parent container, not TabItem ). I think this gives us a hint why this does not work: a DataTemplate is not created at the point where it is defined in XAML, but apparently by the parent container.

I suppose I can replace the entire ControlTemplate to achieve the effect I'm looking for, but since I want to keep the TabItem look default, without having to support the entire ControlTemplate , I am very reluctant to do this.

Edit

Meanwhile, I found out that the problem is this: TabControl cannot have (any) ItemsTemplate (including DisplayMemberPath ) if the ItemsSource contains Visual s. There is a thread on the MSDN forum explaining why .

Since this seems to be the main issue with WPF TabControl, I close the question. Thank you for your help!

+6
wpf binding xaml datatemplate
source share
2 answers

Try it. I'm not sure if this will work or not, but

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

If this does not work, try pasting this attribute into <TabItem />:

 DataContext="{Binding RelativeSource={RelativeSource self}}" 
+1
source share

It seems like the problem is that you are using a ContentTemplate without actually using the content property. By default, the DataContext for a DataTemplate ContentTemplate is a Content TabItem property. However, none of what I said actually explains why the binding does not work. Unfortunately, I can’t give you the final answer, but I think this is due to the fact that TabControl reuses ContentPresenter to display the content property for all tabs.

So, in your case, I would modify the code to look something like this:

 <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}}" /> 

If ShortLabel is a more complex object, and not just a string, you would like to add a 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> 
+1
source share

All Articles