I've got 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's namespace -->
<TextBlock Text="{Binding ElementName=Self, Path=ShortLabel, UpdateSourceTrigger=PropertyChanged}"/>
This custom TabItem defines a DependencyProperty
'ShortLabel' to implement an interface. I would like to bind to this and other properties from within the TabItem
's DataTemplate
. But due to strange interactions, the TextBlock
within the DataTemplate
gets bound to the parent container of the TabItem
, which also is called "Self", but defined in another Xaml file.
Why does the Binding work in the TabItem.Header, but not from within TabItem.ContentTemplate, and how should I proceed to get to the user control's properties from within the DataTemplate?
TemplateBinding
: Tries to bind to the ContentPresenter within the guts of the TabItem
.FindAncestor, AncestorType={x:Type TabItem}
: Doesn't find the TabItem
parent. This doesn't work either, when I specify the MyTabItem
type.ElementName=Self
: Tries to bind to a control with that name in the wrong scope (parent container, not TabItem
). I think that gives a hint, why this isn't working: the DataTemplate is not created at the point where it is defined in XAML, but apparently by the parent container.I assume I could replace the whole ControlTemplate
to achieve the effect I'm looking for, but since I want to preserve the default look and feel of the TabItem
without having to maintain the whole ControlTemplate
, I'm very reluctant to do so.
Meanwhile I have found out that the problem is: TabControl
s can't have (any) ItemsTemplate
(that includes the DisplayMemberPath
) if the ItemsSource
contains Visual
s. There a thread on MSDN Forum explaining why.
Since this seems to be a fundamental issue with WPF's TabControl, I'm closing the question. Thanks for all your help!
What appears to be the problem is that you are using a ContentTemplate without actualy using the content property. The default DataContext for the ContentTemplate's DataTemplate is the Content property of TabItem. However, none of what I said actually explains why the binding doesn't work. Unfortunately I can't give you a definitive answer, but my best guess is that it is due to the fact that the TabControl reuses a ContentPresenter to display the content property for all tab items.
So, in your case I would change 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 then you would want to indroduce 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>
Try this. I'm not sure if it 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 it doesn't work, try sticking this attribute in the <TabItem/>:
DataContext="{Binding RelativeSource={RelativeSource self}}"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With