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).
source share