Silverlight ListBox mit kontextabhängigem ItemTemplate

In einer ListBox von Silverlight 4 sollen .NET Objekte dargestellt werden, die zwar einer gemeinsamen Basisklasse angehören, individuell aber unterschiedliche Ausprägungen haben – im Beispiel habe ich mal eine abstrakte Basisklasse Animal (Tier) genommen und davon Insect (Insekten), Mammal (Säugetiere) und Bird (Vögel) abgeleitet. Im realen Leben soll die ListBox für die unterschiedlichen konkreten Klassen völlig unterschiedliche Darstellungen verwenden. Im Beispiel habe ich hier einfach mal einen Präfix und eine Farbunterlegung verwendet.

Beispiel

Links sieht man die normale Darstellung und rechts so, wie ich mir das vorstelle. Den gesamten Quellcode für das Beispiel habe ich hier bereitgestellt, hier nur kurz die wesentlichen Tricks (wenn es einfacher geht, wäre ich durchaus an einem Hinweis interessiert).

Die rechte ListBox verwendet ein ItemTemplate / DataTemplate, in dem eine dynamische Bindung des Styles an ein ContentControl vorgenommen wird.

<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl Style="{Binding Converter={StaticResource style}}" />
</DataTemplate>
</ListBox.ItemTemplate>

Bei der statischen Ressource handelt es sich um einen IValueConverter, der nach einer Namenskonvention beliebigen Instanzen von .NET Objekten eine statische XAML Ressource zuordnet.

<app:StyleChooser x:Key="style" />

object IValueConverter.Convert( object value, Type targetType, object parameter, CultureInfo culture )
{
if (value == null)
return null;
else if (targetType == typeof( Style ))
return App.Current.Resources[value.GetType().Name + "ClassStyle"];
else
return null;
}

Nun muss nur noch für jede Klasse ein Style in der verwendete Namenskonvention bereitgestellt werden. Da hier ein ContentControl verwendet wird, hat man im ControlTemplate alle Möglichkeiten, die auch ein DataTemplate bietet.

<Style x:Key="MammalClassStyle" TargetType="ContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel Background="Gray" Orientation="Horizontal">
<TextBlock Text="Das ist ein Säugetier: " />
<TextBlock Text="{Binding}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Happy Coding

Jochen

Bookmark the permalink.

Schreibe einen Kommentar