SilverLight – ListBox mit multiplen ListBoxItem Templates

Abgelegt unter: Allgemeines am: 10. November 2010 | | Kommentare (2)

Manchmal macht es Sinn die ListBoxItems in der ListBox unterschiedlich darzustellen. Um dies zu machen müsste man das Template beim Erstellen eines ListBoxItems zuweisen. Das ganze kann man leicht mit einem einfachen ValueConverter erreichen.

Angenommen wir haben in unseren Model eine Eigenschaft anhand deren wir das Template wählen möchten. Falls man Objekte mit unterschiedlichen Typen bindet und anhand des Typen das Template wählen möchte dann bindet man das ganze Objekt an die Style Eigenschaft des ListBoxItems und passt den Converter dem entsprechend an.

public enum ItemType
{
	Default,
	Editable
}
 
public class ItemViewModel : INotifyPropertyChanged
{
	private ItemType _type;
	public ItemType ItemType
	{
		get { return _type; }
		set
		{
			if (value != _type)
			{
				_type = value;
				NotifyPropertyChanged("ItemType");
			}
		}
	}
 
	...

Damit man aus dem ValueConverter der kein FrameworkElement ist trozdem Ressourcen findet brauchen wir eine Helper Klasse die nach Ressourcen sucht. Man könnte es auch weglassen aber ich finde die Klasse ziemlich hilfreich.

public static class ResourceHelper
{
	public static object FindResource(string name)
	{
		if (App.Current.Resources.Contains(name))
			return App.Current.Resources[name];
		else
		{
			FrameworkElement root = App.Current.RootVisual as FrameworkElement;
			return root.FindResource(name);
		}
	}
 
	internal static object FindResource(this FrameworkElement root, string name)
	{
		if (root != null && root.Resources.Contains(name))
			return root.Resources[name];
		else
		{
			try
			{
				return root.FindName(name);
			}
			catch { }
		}
 
		return null;
	}
}

Der ValueConverter konvertiert den gebundenen Wert in die Ressource. Die ConvertBack Methode braucht man in diesem Fall nicht.

public class ListBoxItemTemplateConverter : IValueConverter
{
	public object Convert(object value, System.Type targetType, object parameter, 
		System.Globalization.CultureInfo culture)
	{
		return ResourceHelper.FindResource(string.Format("ListBoxItem{0}Style", 
			value.ToString())); 
	}
 
	public object ConvertBack(object value, System.Type targetType, object parameter, 
		System.Globalization.CultureInfo culture)
	{
		throw new System.NotImplementedException();
	}
}

Jetzt muss man die eigentlichen Ressourcen definieren, es sind Styles mit dem TargetType ListBoxItem

<local:ListBoxItemTemplateConverter x:Key="ListBoxItemTemplateConverter"/>
 
<Style x:Key="ListBoxItemDefaultStyle" TargetType="ListBoxItem">
	<Setter Property="Template">
		<Setter.Value>
			<ControlTemplate TargetType="ListBoxItem">
				<StackPanel Margin="0,0,0,17" Width="432" >
					<TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" 
						Style="{StaticResource PhoneTextExtraLargeStyle}"/>
					<TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" 
						Margin="12,-6,12,0" 
						Style="{StaticResource PhoneTextSubtleStyle}"/>
				</StackPanel>
			</ControlTemplate>
		</Setter.Value>
	</Setter>
</Style>
 
<Style x:Key="ListBoxItemEditableStyle" TargetType="ListBoxItem">
	<Setter Property="Template">
		<Setter.Value>
			<ControlTemplate TargetType="ListBoxItem">
				<StackPanel Margin="0,0,0,17" Width="432" >
					<TextBox Text="{Binding LineOne, Mode=TwoWay}" />
					<TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" 
						Margin="12,-6,12,0" 
						Style="{StaticResource PhoneTextSubtleStyle}"/>
				</StackPanel>
			</ControlTemplate>
		</Setter.Value>
	</Setter>
</Style>

Und jetzt kommt der eigentliche Trick, man erstellt ein DataTemplate in der ein ListBoxItem ist dessen Style Eigenschaft über den ValueConverter an die Eigenschaft des Models gebunden ist. Der ValueConverter gibt dann einfach die passende Ressource zurück. Dieser Trick klappt ohne Probleme in Blend.

<ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}" 
	SelectionChanged="MainListBox_SelectionChanged">
	<ListBox.ItemTemplate>
		<DataTemplate>
			<!-- is blendable if you use sample data -->
			<ListBoxItem Style="{Binding Path=ItemType, 
				Converter={StaticResource ListBoxItemTemplateConverter}}" />
 
			<!-- Bind a item  -->
			<!--<ListBoxItem Style="{Binding 
				Converter={StaticResource ListBoxItemTemplateConverter}}" /> --> 
 
			<!-- Works only after compiling -->
			<!--<ListBoxItem Style="{Binding Path=ListBoxItemStyle}" /> --> 
		</DataTemplate>
	</ListBox.ItemTemplate>
</ListBox>

So ‘ne Scheiße

Abgelegt unter: Allgemeines am: 14. Juli 2010 | | Kommentare (1)

Das Gewitter forderte seinen Tribut, nicht nur die Deutsche Bahn hatte damit Probleme ^^

Owned

Firm Projekt – EOS

Abgelegt unter: Allgemeines am: 9. Februar 2010 | | Kommentare (0)

Hi, an der Uni machen wir zurzeit ein Filmprojekt, wir machen ziemlich viel mit 3D wahrscheinlich weil von uns keiner so richtig schauspielern kann XD

Jedenfalls wollte ich mal eine der Szenen aus dem Film zeigen, die Szene wurde mit 3ds Max, After Effects und etwas Photoshop erstellt :)


Foo

Speedpaint #2

Abgelegt unter: Allgemeines am: 31. Januar 2009 | Schlagwörter:, | Kommentare (0)

he's back

Speedpaint #1

Abgelegt unter: Allgemeines am: 29. Januar 2009 | Schlagwörter:, | Kommentare (0)

manonfire

ein Blick in aruss labor XD

Abgelegt unter: Allgemeines am: 18. Oktober 2008 | | Kommentare (5)

Nanometa – Technikkultur in Neuss

Abgelegt unter: Allgemeines am: 21. August 2008 | Schlagwörter: | Kommentare (1)

Nun hat nanometa eine neue Frontpage :)

Das Wiki existiert nach wie vor und kann unter http://www.nanometa.de/wiki erreicht werden.

Stöbert gerne mal durch das Wiki und falls ihr interessiert seit wir suchen immer noch nach Mitstreitern :)

Pen & Paper

Abgelegt unter: Allgemeines am: 11. August 2008 | Schlagwörter: | Kommentare (0)

Habe entlich meinen Scanner wieder zum laufen gebracht und direkt ein Paar meiner Meinung nach sehenswerte Zeichnungen eingescannt :)

sketch1 sketch2 sketch3 sketch2 sketch5

Ich werde die Tage, wenn ich Zeit finde also ich mein wenn ich nicht so faul bin, meine restlichen Zeichnungen einscannen und in der Gallerie online stellen.

Which Programming Language are You?

Abgelegt unter: Allgemeines am: 23. August 2007 | Schlagwörter:, | Kommentare (0)

You are C#. No matter how hard you try, you can't convince people that you are unique.  You're composed of others' traits.

Zu lustig ^^ zufällig Programmiere ich schon seit ca. zwei Jahren fast nur noch C#.