Reputation: 389
I've got a ObservableCollection<IContainers> Containers
which defines the property ObservableCollection<object> Content
.
public interface IContainers
{
public double Height {get; set;}
public double Width {get; set;}
public ObservableCollection<object> Content {get; set;}
}
public class SetupStep
{
public ObservableCollection<IContainer> Containers {get; set;}
}
The types of items in the Content
Property can vary. These types define their own properties to which I want to bind.
This is my .xaml code:
<c:ScatterView
ItemsSource="{Binding Containers}">
<c:ScatterView.ItemTemplate>
<DataTemplate>
<ListBox
ItemsSource="{Binding Content}">
<!--A way to determine my types in Contents?!?!-->
<ListBox.Resources>
<DataTemplate x:Key="{x:Type myObjects:Picture}">
<Image Source="{Binding Picture.FullFileName}"/>
</DataTemplate>
<DataTemplate x:Key="{x:Type myObjects:Parameter}">
<myControl:ParameterControl Id="{Binding Parameter.Id}"/>
</DataTemplate>
</ListBox.Resources>
<!--A way to determine my types in Contents?!?!-->
</ListBox>
</DataTemplate>
</c:ScatterView.ItemTemplate>
</c:ScatterView>
I found no working solution to bind to the properties of myObjects like Picture
or Parameter
.
I hope for some ideas :) Thanks, Alex
Upvotes: 0
Views: 53
Reputation: 128060
Data Templates and Binding source properties are resolved by reflection. So if the Content
collection contains a Picture
, a DataTemplate for Picture
can be applied automatically.
The only thing you need to do is to set the DataType
property of the DataTemplate:
<ListBox.Resources>
<DataTemplate DataType="{x:Type myObjects:Picture}">
<Image Source="{Binding Picture.FullFileName}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type myObjects:Parameter}">
<myControl:ParameterControl Id="{Binding Parameter.Id}"/>
</DataTemplate>
</ListBox.Resources>
Everything else should work out of the box.
While you could also use a DataTemplateSelector
, the above approach is far simpler. Using a DataTemplateSelector isn't necessary unless you want to have different DataTemplates for different items of the same type, e.g. depending on the value of some property of the item class.
Upvotes: 3
Reputation: 4298
You might want to take a look at the DataTemplateSelector class. This allows you to switch DataTemplate
depending on different criteria - in your case, this criteria could be the list item type:
public class CustomDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is MainWindow.Picture)
return PictureTemplate;
if (item is MainWindow.Parameter)
return ParameterTemplate;
// return some default template as fall-back
}
public DataTemplate PictureTemplate { get; set; }
public DataTemplate ParameterTemplate { get; set; }
// ...add other template references here...
}
You can now define all templates as XAML resources, and simply reference the TemplateSelector within the ListBox
:
<Window.Resources>
<DataTemplate x:Key="PictureTemplate">
<Image Source="{Binding FullFileName}"/>
</DataTemplate>
<DataTemplate x:Key="ParameterTemplate">
<myControl:ParameterControl Id="{Binding Id}"/>
</DataTemplate>
...add other templates here...
<local:CustomDataTemplateSelector x:Key="CustomDataTemplateSelector"
PictureTemplate="{StaticResource PictureTemplate}"
ParameterTemplate="{StaticResource ParameterTemplate}"/>
</Window.Resources>
<ListBox
ItemsSource="{Binding Content}"
ItemTemplateSelector="{StaticResource CustomDataTemplateSelector}">
</ListBox>
Upvotes: 1