Question

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.

Était-ce utile?

La 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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top