Reputation: 23254
public class Meh : DependencyObject
{
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(string), typeof(Meh));
public string MyProperty
{
get { return (string)GetValue(MyPropertyProperty); }
set { SetValue(MyPropertyProperty, value); }
}
}
Now I databind that to a tab control using the following code
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
var data = new List<Meh>();
data.Add(new Meh { MyProperty = "One" });
data.Add(new Meh { MyProperty = "Two" });
TabControlViews.ItemsSource = data;
}
}
The XAML for the tab control looks like this
<TabControl Name="TabControlViews">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding MyProperty}"/>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
This works fine and the tabs "One", "Two" appear on the tab control. However if I change the base type of Meh from DependencyObject to UserControl the tabs are blank. Why is this?
Upvotes: 4
Views: 3593
Reputation: 41403
The issue is with how ItemsControls work. For ListBox, it's items are "wrapped" with a ListBoxItem (assuming the item isn't a ListBoxItem). So if you add a UserControl as an item to a ListBox, it will ultimately end up in the ListBoxItem.Content property and presented.
With TabControl, its items are wrapped with a TabItem. Unlike ListBoxItem, TabItem derives from HeaderedContentControl. So again if you add a UserControl as an item to a TabControl, it will ultimately end up in the TabItem.Content property and present.
Now, if the item being added is not a visual (such as a DependencyObject) then the item will also be assigned to the TabItem.Header property. So in your case, by switching the base class from DependencyObject to UserControl, you are toggling this behavior.
The reason a visual is not set to both TabItem.Content and TabItem.Header is because then it could end up in the visual tree in two locations, which is bad.
EDIT:
Also, the ItemTemplate is passed down to the TabItem.HeaderTemplate, not TabItem.ContentTemplate (which is the case for ListBoxItem).
Upvotes: 1
Reputation: 2385
I ran into this problem as well, and I just found this:
Binding for TabItem's content controls
It looks like rather than using the ItemTemplate and ContentTemplate properties, you can just create an ItemContainerStyle. I don't know why it works, but it worked for me.
Obviously, this is a little late for Peter, but maybe it will help the next person stumbling on this.
Upvotes: 1
Reputation: 14111
EDIT
I've checked your code, and it seems that at runtime, the ContentPresenter of the TabItem does not inherit the DataContext from the TabControl as soon the item to display is of type Visual or derived from it.
This smells like some TabControl funny behaviour, since replacing TabControl with ListBox works fine. As to the specific cause of the problem, it isn't apparent to me.
Upvotes: 2