Why can't WPF bind to UserControl properties?

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 bind it to the 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 is as follows:

 <TabControl Name="TabControlViews"> <TabControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding MyProperty}"/> </DataTemplate> </TabControl.ItemTemplate> </TabControl> 

This works fine, and the One, Two tabs appear in the tab control. However, if I change the base Meh type from DependencyObject to UserControl, the tabs are empty. Why is this?

+4
source share
3 answers

I ran into this problem and I just found this:

Linking TabItem Content Controls

It seems that instead of the ItemTemplate and ContentTemplate properties, you can simply create an ItemContainerStyle. I don't know why this works, but it worked for me.

Obviously, this is a bit late for Peter, but perhaps it will help the next person stumble upon it.

+1
source

EDIT

I checked your code and it seems that at runtime the ContentPresenter TabItem does not inherit the DataContext from the TabControl as soon as the item to display is of type Visual or is derived from it.

It smells like TabControl's fun behavior, since replacing TabControl with a ListBox works fine. As for the specific cause of the problem, this is not obvious to me.

+2
source

The problem is how ItemsControls work. For a ListBox, items are "wrapped" using a ListBoxItem (if the item is not a ListBoxItem). Therefore, if you add UserControl as an element to the ListBox, it will end up in the ListBoxItem.Content property and be presented.

With TabControl, its elements are wrapped with TabItem. Unlike ListBoxItem, TabItem comes from HeaderedContentControl. Therefore, if you add a UserControl element as an element to TabControl, it will end up in the TabItem.Content property and present.

Now, if the added item is not visual (for example, DependencyObject), then the item will also be assigned to the TabItem.Header property. Therefore, in your case, switching the base class from DependencyObject to UserControl, you will switch this behavior.

The reason the visual is not configured for both TabItem.Content and TabItem.Header, because then it can appear in the visual tree in two places, which is bad.

EDIT:

In addition, the ItemTemplate is passed to TabItem.HeaderTemplate, and not to TabItem.ContentTemplate (which refers to ListBoxItem).

+1
source

All Articles