Entwickler-Ecke
WPF / Silverlight - Styles und Subelemente
UGrohne - Mi 04.02.09 21:18
Titel: Styles und Subelemente
Hallo,
ich setze mich gerade tief mit WPF auseinander und habe dafür u.a. ein DataTemplate für eine ListBox erstellt, in dem ein StackPanel mit mehreren TextBlocks drin ist.
Diese Blöcke möchte ich gern formatieren, ohne jedem TextBlock manuell einen Style zuweisen zu müssen. Gibt es eine Möglichkeit über einen Style für das StackPanel auch Eigenschaften der Unterelemente, z.B. alle vom Typ TextBlock zu setzen?
XML-Daten
1: 2: 3: 4:
| <Style x:Key="StackPanelForListBox" TargetType="{x:Type StackPanel}"> <Setter Property="Height" Value="15"/> <Setter Property="Orientation" Value="Horizontal"/> </Style> |
Kha - Do 05.02.09 12:38
Titel: Re: Styles und Subelemente
UGrohne hat folgendes geschrieben : |
| Gibt es eine Möglichkeit über einen Style für das StackPanel auch Eigenschaften der Unterelemente, z.B. alle vom Typ TextBlock zu setzen? |
Da fallen mir zwei verschiedene Möglichkeiten ein:
- Property Value Inheritance: DPs wie TextBlock.FontSize werden vom Parent an seine Children "vererbt". Man kann dazu auch einem StackPanel diese Property zuweisen, das selbst ja eigentlich nichts damit anfangen kann.
XML-Daten
1: 2:
| <StackPanel> <TextBlock.FontSize>... |
- Implicit Styles: Styles mit TargetType und ohne x:Key werden automatisch auf alle Children des Typs (wenn sie keinen eigenen Style haben) angewendet. Du müsstest also im Style StackPanel.Resources auf ein neues ResourceDictionary mit dem implicit Style setzen. Hab ich zwar noch nie gemacht :nut:, sollte aber funktionieren.
PS: Ganz schlau bin ich aus dem Aufbau aber nicht geworden. Wofür ein eigener Style für das Panel?
UGrohne - Do 05.02.09 14:41
OK, die erste Möglichkeit werde ich mal probieren, wenn mein Rechner wieder tut (im Augenblick sitze ich an einem MacBook).
Wofür? Im ersten Moment dachte ich, ich mache ein DataTemplate für die ListBox. Da mein DataContext Objekte mit mehreren Eigenschaften beinhaltet, von denen ich mehrere anzeigen möchte, habe ich ein StackPanel in das DataTemplate gebaut, das mir mehrere Eigenschaften über mehrere TextBlocks anzeigt (siehe oben). Ich werde aber mehrere dieser DataTemplates haben (für jede Klasse, die ich auflisten werde) und möchte ich mir die Arbeit ersparen, immer einen Style zum TextBlock zuweisen zu müssen.
Inzwischen bin ich aber auf die Alternative des Converters gekommen, mit dem ich mehrere Eigenschaften in einem TextBlock anzeigen lassen kann, indem ich einen FormatConverter schreibe, der die Methode String.Format verwendet, um alle Elemente zusammenzubauen :)
Kha - Do 05.02.09 20:29
UGrohne hat folgendes geschrieben : |
| OK, die erste Möglichkeit werde ich mal probieren, wenn mein Rechner wieder tut (im Augenblick sitze ich an einem MacBook). |
Noch ein Hinweis: In der Doku steht, welche DPs das unterstützen:
Quelltext
1: 2: 3: 4: 5: 6:
| Dependency Property Information Identifier field FontSizeProperty Metadata properties set to true AffectsMeasure, AffectsRender, Inherits |
UGrohne hat folgendes geschrieben : |
| Inzwischen bin ich aber auf die Alternative des Converters gekommen, mit dem ich mehrere Eigenschaften in einem TextBlock anzeigen lassen kann, indem ich einen FormatConverter schreibe, der die Methode String.Format verwendet, um alle Elemente zusammenzubauen :) |
Ja, die Dinger sind nützlich, wären sie nicht so unglaublich hässlich :D . Eine ganze Klasse für eine bis ein paar Zeilen... Da würde ich den String lieber direkt in der Datenklasse generieren lassen (ToString/neue Property) oder gleich mein neues Lieblingsspielzeug MVVM benutzen :D . Denn das ist eine der Aufgaben des ViewModels: Das Model so aufbereiten, dass XAML was mit anfangen kann.
UGrohne - Do 05.02.09 21:37
OK, das mit dem Inherit funktioniert teilweise, lediglich beim Background-Brush scheint es nicht zu gehen:
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| <Style x:Key="StackPanelForListBox" TargetType="{x:Type StackPanel}"> <Setter Property="Height" Value="15"/> <Setter Property="RenderTransformOrigin" Value="0.5,0.5"/> <Setter Property="TextBlock.Margin" Value="2,10,2,10"/> <Setter Property="Orientation" Value="Horizontal"/> <Setter Property="TextBlock.Background"> <Setter.Value> <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> <GradientStop Color="#00FF0000" Offset="0"/> <GradientStop Color="#FF000000" Offset="1"/> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property="TextBlock.Height" Value="20"/> <Setter Property="TextBlock.FontWeight" Value="Bold"/> </Style> |
Der Rest passt :)
Kha hat folgendes geschrieben : |
| Ja, die Dinger sind nützlich, wären sie nicht so unglaublich hässlich :D . Eine ganze Klasse für eine bis ein paar Zeilen... Da würde ich den String lieber direkt in der Datenklasse generieren lassen (ToString/neue Property) oder gleich mein neues Lieblingsspielzeug MVVM benutzen :D . Denn das ist eine der Aufgaben des ViewModels: Das Model so aufbereiten, dass XAML was mit anfangen kann. |
So hässlich finde ich sie nicht, sind doch schnell erstellt ;). Einzig, dass dann das Bearbeiten in Blend nicht mehr funktioniert, nervt ein wenig. Aber zum MVVM hab ich auch schon ein Dokument auf dem Schreibtisch liegen. Das kommt morgen dran, sobald ich die Grundlagen zum Entity Framework noch drauf habe ;)
Kha - Fr 06.02.09 12:40
UGrohne hat folgendes geschrieben : |
| OK, das mit dem Inherit funktioniert teilweise, lediglich beim Background-Brush scheint es nicht zu gehen: |
Ja, Background wird nicht vererbt, da müsstest du also zum Style im Style greifen. Oder etwas einfacher: Deklariere den TextBlock-Style in den Resources deiner ListBox. Der Scope des Styles ist dann zwar etwas größer, dürfte aber wohl zum gleichen Ergebnis führen.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!