I am assuming that you will put some kind of objects representing these name/value pairs into an ItemsControl
by setting its ItemsSource
property.
There are a couple of solutions you can use.
Using a DataTemplate
with triggers:
This approach involves exposing the "type" of each of your objects through the YourPropertyType
property as a string. You will set the ItemTemplate
of your ItemsControl
to a template which hosts a ContentControl
. The ContentControl
itself will have its ContentTemplate
selected dynamically with triggers.
All of this can be done declaratively in XAML.
I am assuming you have further DataTemplates
named DefaultTemplate
(this can be empty), IntegerTemplate
, StringTemplate
, etc to sketch out the visual tree for each case.
This would then be the ItemsControl.ItemTemplate
:
<DataTemplate>
<ContentControl
x:Name="MyContentControl"
Content="{Binding}"
ContentTemplate="{StaticResource DefaultTemplate}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding YourPropertyType}" Value="Integer">
<Setter TargetName="MyContentControl" Property="ContentTemplate"
Value="{StaticResource IntegerTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding YourPropertyType}" Value="String">
<Setter TargetName="MyContentControl" Property="ContentTemplate"
Value="{StaticResource StringTemplate}" />
</DataTrigger>
<!-- and so on -->
</DataTemplate.Triggers>
</DataTemplate>
Using a DataTemplateSelector
:
This approach requires code-behind, but it does not force you to expose the "type" of each name/value pair as a string and it allows you to choose which template to use with much more complex logic.
It involves creating a class to be the template selector:
class YourObjectDataTemplateSelector : DataTemplateSelector
{
public DataTemplate DefaultTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var yourObject = (YourObjectType) item;
// Get hold of a DataTemplate based on any attribute of item
var templateToUse = this.DefaultTemplate;
return templateToUse;
}
}
Then, you need to instantiate a template selector somewhere (let's say inside your UserControl
)
<UserControl.Resources>
<localNamespace:YourObjectDataTemplateSelector
x:Key="TemplateSelector"
DefaultTemplate="{StaticResource DefaultTemplate}"
/>
</UserControl.Resources>
Notice that I exposed a DefaultTemplate
property from YourObjectDataTemplateSelector
and set that to a template from XAML. In practice, you would define more properties of type DataTemplate
on YourObjectDataTemplateSelector
, and "configure" the template selector when adding it into the resource dictionary of your control. This allows you to directly set the templates for each case using the StaticResource
markup extension from XAML.
Finally, wire the template selector to your ItemsControl
:
<ItemsControl
ItemsSource="..."
ItemTemplateSelector={StaticResource TemplateSelector}"
/>