Styles sind in WPF eine Möglichkeit, visuelle Eigenschaften, die für mehrere Controls gelten sollen, an zentraler Stelle zu definieren und den Controls zuzuweisen. Dies erspart zum Einen Schreibaufwand und zum Anderen Zeit, wenn eine dieser Einstellungen geändert werden soll. In diesem Post soll es aber nicht um die Basics von Styles gehen, sondern um den Anwendungsfall, dass man einen Style für alle Controls eines bestimmten Typs definiert.
Nehmen wir an, wir haben ein Window mit zwei GroupBoxes, die jeweils zwei TextBlocks enthalten:
<Window x:Class="StylesExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Styles" Height="200" Width="200">
<StackPanel>
<GroupBox Header="Vornamen">
<StackPanel>
<TextBlock Text="Petra" />
<TextBlock Text="Michael" />
</StackPanel>
</GroupBox>
<GroupBox Header="Nachnamen">
<StackPanel>
<TextBlock Text="Müller" />
<TextBlock Text="Meier" />
</StackPanel>
</GroupBox>
</StackPanel>
</Window>
Sieht als Ergebnis so aus:

Nun wollen wir allen TextBlocks einen gelben Hintergrund und einen Margin von 3 verpassen. Ein Weg wäre, den Style in den Window-Ressourcen zu definieren und bei jedem TextBlock das Style-Property anzugeben. Dies bedeutet aber wieder, dass wir bei jedem zusätzlichen TextBlock mehr schreiben müssen. Schöner wäre es doch, wenn wir direkt angeben könnten, dass der Style für alle TextBlock-Controls gelten soll. Dies geschieht, indem man einem Style nur den TargetType mitgibt, aber keinen Key:
<Window.Resources>
<Style TargetType="TextBlock" >
<Setter Property="Background" Value="Yellow" />
<Setter Property="Margin" Value="3" />
</Style>
</Window.Resources>
Starten wir die Anwendung jetzt, sieht das Ergebnis folgendermaßen aus:

Da wir den Style in den Ressourcen des Windows definiert haben, wird er auf alle TextBlock-Controls innerhalb des Windows angewendet. Würden wir ihn in den Ressourcen einer der GroupBoxes definieren, würde er nur für die TextBlock-Controls dieser GroupBox gelten. Möchten wir also, dass die Vornamen einen hellgrünen Hintergrund bekommen, definieren wir einen neuen Style innerhalb der ersten GroupBox:
<GroupBox.Resources>
<Style TargetType="TextBlock" >
<Setter Property="Background" Value="LightGreen" />
<Setter Property="Margin" Value="3" />
</Style>
</GroupBox.Resources>

Für alle TextBlock-Controls der Vornamen-GroupBox gilt nun der Style aus den GroupBox-Ressourcen, während für alle anderen TextBlock-Controls weiterhin der Style aus den Window-Ressourcen gilt.
Jetzt kann es aber natürlich vorkommen, dass eines der TextBlock-Controls einen abweichenden Style bekommen soll, zum Beispiel wenn der TextBlock “Meier” fett erscheinen soll. Kein Problem, setzen wir einfach einen Style für das Control:
<TextBlock Text="Meier">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold" />
</Style>
</TextBlock.Style>
</TextBlock>

Wie wir sehen, führt uns das aber nicht wirklich zum Ziel. Die Schrift ist jetzt zwar fett, aber der Standard-Style ist verloren gegangen. Wir müssen also einen Weg finden, um den neuen Style auf dem Standard-Style basieren zu lassen. Dazu bietet jeder Style ein BasedOn-Property, über das der Basis-Style für den Style angegeben werden kann. Nun haben die Styles, die für alle Controls in ihrem Kontext gelten, aber keinen Key, über den wir sie ansprechen können. Zumindest keinen, den wir angegeben haben. Intern vergibt WPF aber dennoch einen Key, nämlich den Type des Target-Controls. Und über diesen können wir den Standard-Style ansprechen:
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="FontWeight" Value="Bold" />
</Style>
So kommen wir zu unserem gewünschen Ergebnis:

Verfasst von chefarbeiter 


