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.
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>