SL3 TabItem HeaderTemplate does not support DataBinding - PRISM work-around

An excerpt from this message thread on follows:

TabControl and Databinding is a sore point for a while now. You can show your support in fixing it on this codeplex bug: 

We're planning on overhauling TabControl for the Silverlight vNext release.


Justin Angel,
Blog @
Twitter @

The problem reveals itself in the PRISM View Injection QuickStart: 

Since PRISM has a TabcontrolRegionAdapter for Silverlight we have a hook into the problem (for a work-around).  Excerpt from documentation on the BootStrapper follows:

Conditional compiling is used to register the TabControlRegionAdapter only for Silverlight. This is because when you add an item in a TabControl control in WPF, this item is wrapped inside a TabItem type. This is not applicable for Silverlight, where you must manually wrap the item into the TabItem; because of that, the TabControlRegionAdapter adapter was modified to both adapt a region to the TabControl control and to automatically add this wrapping.

PRISM users can update the TabControlRegionAdapter.cs, in the Composite.Presentation project, as follows:

private static TabItem PrepareContainerForItem(object item, DependencyObject parent)
TabItem container = item as
if (container == null
    container = new
    container.Content = item;
    container.DataContext = GetDataContext(item);
    container.Style = GetItemContainerStyle(parent);
    container.SetValue(IsGeneratedProperty, true

    // BillKrat.2009.08.06 - SL3 Template binding bug workaround

    if (container.Header != null
         && container.Header.ToString().Contains("Binding:"
     PropertyInfo modelProperty = null

     // Strip "Binding:" from the header - leaving model property

     string modelPropName = container.Header.ToString().Replace("Binding:", ""

     // Get model properties and search for the property name provided

     PropertyInfo[] propInfo = container.DataContext.GetType().GetProperties();

if (propInfo != null
        modelProperty =
         propInfo.FirstOrDefault(p => p.Name.ToString() == modelPropName);

     // If found then update the header with the value

     if (modelProperty != null
        container.Header = modelProperty.GetValue(modelProperty, null


Instead of using Value="{Binding HeaderInfo}", which won't work under SL3, you can use "Binding:HeaderInfo" which will be processed by the above method.  (note: Header will be set/available when the container.Style property is set above).  An example follows:

    <Style TargetType="Controls:TabItem">
        <Setter Property="Header" Value="Binding:HeaderInfo"/>

Until the Silverlight Toolkit team resolves the issue this can serve as a work-around.   With some work it could be made more dynamic but this is a good starting point.


The model being used follows:

namespace UIComposition.Modules.Project
    public class
        public ObservableCollection<BusinessEntities.Project> Projects { get; set
; }

        public static string
            get { return "Current Projects"
; }

EDITED - a better solution was provided on the following link.  Although I haven't tested it yet I was impressed that it resolves the problem with one line of code - my kind of fix!   I found the above to be a great learning exercise in the power of styles so I leave it intact as is.

PRISM User forum addressing the issue HERE

Tags: , , , ,
Categories: CompositeWPF

Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know