Search code examples
silverlighttelerikcontroltemplatedatatemplateselectorcontenttemplateselector

Binding a data template selector to a content control template


I would like to bind a content control to a data template selector, bind a variable to that content control and then display a different template depending on what the variable contains.

I've managed to get a Telerik DataTemplateSelector to do what I need it to, however I can't find a control to bind the DataTemplateSelector to.

All of the controls that I've found that allow me to use a DataTemplateSelector require the ItemsSource to be a collection, if I pass in a single object it throws an exception.

The item I'm passing in is a single item not a collection. The content control seems to be what I need but i can't bind a DataTemplateSelector to it.

Is there a telerik control similar to the Content Control, that I can bind a DataTemplateSelector to? Or is there something similar to a DataTemplateSelector that I can bind to a Content Control.

Any help would be greatly appreciated.


Solution

  • I think you should consider avoiding Telerik's classes (which, in my opinion, complicate the things a bit in this case).

    What about a standard DataTemplateSelector implementation? It's very easy to implement by yourself!

    First you declare a "classic" implementation of the abstract class DataTemplateSelector:

    public abstract class DataTemplateSelector : ContentControl
    {
        public virtual DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            return null;
        }
    
        protected override void OnContentChanged(object oldContent, object newContent)
        {
            base.OnContentChanged(oldContent, newContent);
    
            ContentTemplate = SelectTemplate(newContent, this);
        }
    }
    

    Then you can write you custom DataTemplateSelector...

    public class myTemplateSelector : DataTemplateSelector
    {
        public DataTemplate Template1 { get; set; }
    
        public DataTemplate Template2 { get; set; }
    
    
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            // No template...
            if (item == null)
                return null;
    
            // Enumeration discriminant:
            if (item is BoundTemplateDiscriminantType)
                switch ((BoundTemplateDiscriminantType)item)
                {
                    case BoundTemplateDiscriminantType.Type1:
                        return Template1;
                    case BoundTemplateDiscriminantType.Type2:
                        return Template2;
                    // Not implemented...
                    default:
                        throw new NotImplementedException();
                }
            // Integer discriminant:
            else if (item is int)
            {
                return (int)item > 0 ? Template1 : Template2;
            }
            // Other discriminants...
            else
                // Not yet implemented...
                throw new NotImplementedException();
        }
    }
    

    ...and finally the XAML designing (not the usual ListBoxItem, but a scrollable content in this case):

    <ScrollViewer>
        <ScrollViewer.ContentTemplate>
            <DataTemplate>
                <utilities:myTemplateSelector Content="{Binding Path=BoundDiscriminant, Mode=OneWay}">
                    <!--Content of first template...-->
                    <utils:myTemplateSelector.Template1>
                        <DataTemplate>
                              <TextBlock Text={Binding Path=BoundDescription, Mode=OneWay} />              
                        </DataTemplate>
                    </utils:myTemplateSelector.Template1>
                    <!--Content of second template...-->
                    <utils:myTemplateSelector.Template2>
                        <DataTemplate>
    
                        </DataTemplate>
                    </utils:myTemplateSelector.Template2>
                    ... and so on...
                </utilities:myTemplateSelector>
            </DataTemplate>
        </ScrollViewer.ContentTemplate>
    </ScrollViewer>