ItemTemplateSelector on TabControl

Topics: Conventions
Dec 26, 2011 at 10:59 PM

I am using a TabControl with CM conventions to display a collection of items. It works well, with the tab header set to the DisplayName on the item, and the view showing up as the content. What I want to do is set a template for the tab item header instead of showing the DisplayName string. I created a DataTemplateSelector subclass, and set the TabControl's ItemTemplateSelector property, as shown below. However, the selector's SelectTemplate() method never gets called.

<TabControl x:Name="Items">
    <TabControl.ItemTemplateSelector>
       <local:UserShellDataTemplateSelector/>
     </TabControl.ItemTemplateSelector>
</TabControl>

What is the  proper approach to accomplish this customization?

BTW, f I set the selector to the ContentTemplateSelector property, the SelectTemplate() method does get called to set the tab item's content. Just can't get it to work with ItemTemplateSelector for the tab item headers.

Dec 27, 2011 at 12:29 AM
Edited Dec 27, 2011 at 12:33 AM

After digging around the source code, I found the problem to be an omission in the ConventionManager class. The class does check for the presence of a ContentTemplateSelector, but does not check for an ItemTemplate Selector. I modified the signature and content of the ApplyHeaderTemplate() method as follows, and now it works properly. The changes are highlighted in red.

public static void ApplyHeaderTemplate(FrameworkElement element, DependencyProperty headerTemplateProperty, DependencyProperty itemTemplateSelectorProperty, Type viewModelType) {
    var template = element.GetValue(headerTemplateProperty);
    var selector = element.GetValue(itemTemplateSelectorProperty);

    if (template != null || selector != null || !typeof(IHaveDisplayName).IsAssignableFrom(viewModelType))
        return;

    element.SetValue(headerTemplateProperty, DefaultHeaderTemplate);
    Log.Info("Header template applied to {0}.", element.Name);
}

The method call was changed to:

ApplyHeaderTemplate(tabControl, TabControl.ItemTemplateProperty, TabControl.ItemTemplateSelectorProperty, viewModelType);

I suppose the next step is to submit as an issue, which I will do. I have not yet been able to test for any side effects of this code change.