Anleitung zum Erstellen eines Stils für ein Steuerelement (WPF .NET)

Mit Windows Presentation Foundation (WPF) können Sie eigene, wiederverwendbare Stile für vorhandene Steuerelemente festlegen. Stile können global auf Apps, Fenster und Seiten oder direkt auf Steuerelemente angewendet werden.

Wichtig

Der Desktopleitfaden zu .NET 7 und .NET 6 ist in Bearbeitung.

Erstellen eines Stils

Style ist eine einfache Möglichkeit, mehrere Eigenschaftswerte auf mindestens ein Element anzuwenden. Stile lassen sich auf alle Elemente anwenden, die von FrameworkElement oder FrameworkContentElement abgeleitet sind, z. B. Window oder Button.

Stile werden üblicherweise deklariert, indem sie im Abschnitt Resources einer XML-Datei als Ressource deklariert werden. Da es sich bei Stilen um Ressourcen handelt, unterliegen sie denselben Regeln für Gültigkeitsbereiche, die für alle Ressourcen gelten. Einfach ausgedrückt: Wo Sie einen Stil deklarieren, bestimmt darüber, wo der Stil angewendet werden kann. Wenn Sie den Stil z. B. im Stammelement Ihrer XML-Datei mit der App-Definition deklarieren, kann der Stil überall in der App verwendet werden.

<Application x:Class="IntroToStylingAndTemplating.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:IntroToStylingAndTemplating"
             StartupUri="WindowExplicitStyle.xaml">
    <Application.Resources>
        <ResourceDictionary>
            
            <Style x:Key="Header1" TargetType="TextBlock">
                <Setter Property="FontSize" Value="15" />
                <Setter Property="FontWeight" Value="ExtraBold" />
            </Style>
            
        </ResourceDictionary>
    </Application.Resources>
</Application>

Wenn Sie den Stil in einer der XAML-Dateien der App deklarieren, ist der Anwendungsbereich des Stils nur auf diese XAML-Datei begrenzt. Weitere Informationen zu Gültigkeitsbereichregeln für Ressourcen finden Sie unter Übersicht über XAML-Ressourcen.

<Window x:Class="IntroToStylingAndTemplating.WindowSingleResource"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:IntroToStylingAndTemplating"
        mc:Ignorable="d"
        Title="WindowSingleResource" Height="450" Width="800">
    <Window.Resources>
        
        <Style x:Key="Header1" TargetType="TextBlock">
            <Setter Property="FontSize" Value="15" />
            <Setter Property="FontWeight" Value="ExtraBold" />
        </Style>
        
    </Window.Resources>
    <Grid />
</Window>

Ein Stil besteht aus untergeordneten <Setter>-Elementen, die Eigenschaften für die Elemente festlegen, auf die der Stil angewendet wurde. Beachten Sie im obigen Beispiel, dass der Stil so konfiguriert ist, dass er über das Attribut TargetType auf TextBlock-Typen angewendet wird. Der Stil legt FontSize auf 15 und FontWeight auf ExtraBold fest. Fügen Sie für jede Eigenschaft, die durch den Stil geändert wird, eine <Setter>-Eigenschaft hinzu.

Implizites Anwenden eines Stils

Style ist eine einfache Möglichkeit, mehrere Eigenschaftswerte auf mehr als ein Element anzuwenden. Sehen Sie sich z. B. die folgenden TextBlock-Elemente und deren Standarddarstellung in einem Fenster an:

<StackPanel>
    <TextBlock>My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

Styling sample screenshot before

Sie können die Standarddarstellung ändern, indem Sie Eigenschaften wie FontSize und FontFamily für jedes TextBlock-Element direkt festlegen. Wenn Ihre TextBlock-Elemente jedoch über gewisse gemeinsame Eigenschaften verfügen sollen, können Sie im Abschnitt Resources der XAML-Datei ein Style-Objekt erstellen. Im folgenden Codeausschnitt ist dies veranschaulicht.

<Window.Resources>
    <!--A Style that affects all TextBlocks-->
    <Style TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
</Window.Resources>

Wenn Sie die Eigenschaft TargetType Ihres Stils auf den Typ TextBlock festlegen und das Attribut x:Key weglassen, wird der Stil auf alle TextBlock-Elemente angewendet, für die der Stil gilt. Üblicherweise sind dies die Elemente in der XAML-Datei.

Nun werden die TextBlock-Elemente wie folgt angezeigt.

Styling sample screenshot base style

Explizites Anwenden eines Stils

Wenn Sie dem Stil ein x:Key-Attribut mit einem Wert hinzufügen, wird der Stil nicht mehr implizit auf die Elemente von TargetType angewendet. Von nun gilt er nur noch für Elemente, die explizit auf den Stil verweisen.

Im folgenden Codeausschnitt wird der Stil aus dem vorherigen Abschnitt dargestellt, jedoch mit dem Attribut x:Key deklariert.

<Window.Resources>
    <Style x:Key="TitleText" TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
</Window.Resources>

Legen Sie die Eigenschaft Style des Elements auf den Wert von x:Key fest, um den Stil anzuwenden. Verwenden Sie dazu wie im folgenden Codeausschnitt eine StaticResource-Markuperweiterung.

<StackPanel>
    <TextBlock Style="{StaticResource TitleText}">My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

Beachten Sie, dass der Stil auf das erste TextBlock-Element angewendet wird, während das zweite TextBlock-Element unverändert bleibt. Der implizite Stil aus dem vorherigen Abschnitt wurde in einen Stil geändert, der durch das Attribut x:Key deklariert wird. Dies bedeutet, dass das einzige Element, für das der Stil gilt, dasjenige Element ist, das direkt auf den Stil verweist.

Styling sample screenshot textblock

Wenn ein Stil explizit oder implizit angewendet wird, wird er „versiegelt“ und kann nicht mehr geändert werden. Wenn Sie einen übernommenen Stil ändern möchten, müssen Sie einen neuen Stil erstellen oder den bestehenden ersetzen. Weitere Informationen finden Sie in den Ausführungen zur IsSealed-Eigenschaft.

Sie können ein Objekt erstellen, das einen Stil auf Grundlage einer benutzerdefinierten Logik auswählt. Ein Beispiel finden Sie im Artikel zur Klasse StyleSelector.

Programmgesteuertes Anwenden eines Stils

Rufen Sie den Stil aus der Ressourcenauflistung ab, und weisen Sie ihn der Style-Eigenschaft des Elements zu, um einem Element programmgesteuert einen bestimmten Stil zuzuweisen. Die Elemente in einer Ressourcenauflistung gehören zum Typ Object. Daher müssen Sie den abgerufenen Stil in ein System.Windows.Style-Element umwandeln, bevor Sie ihn der Eigenschaft Style zuweisen können. Im folgenden Code wird z. B. der Stil eines TextBlock-Elements namens textblock1 auf den definierten Stil TitleText festgelegt.

textblock1.Style = (Style)Resources["TitleText"];
textblock1.Style = CType(Resources("TitleText"), Windows.Style)

Erweitern eines Stils

In manchen Situationen ist es erforderlich, dass Ihre beiden TextBlock-Elemente gewisse Eigenschaftswerte gemeinsam haben, z. B. FontFamily und HorizontalAlignment (zentriert). Sie möchten jedoch auch, dass der Text My Pictures (Meine Bilder) einige zusätzliche Eigenschaften hat. Erstellen Sie in diesem Fall einen neuen Stil, der auf dem ersten Stil basiert. Wie das funktioniert, wird im folgenden Codeausschnitt gezeigt.

<Window.Resources>
    <!-- .... other resources .... -->

    <!--A Style that affects all TextBlocks-->
    <Style TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
    
    <!--A Style that extends the previous TextBlock Style with an x:Key of TitleText-->
    <Style BasedOn="{StaticResource {x:Type TextBlock}}"
           TargetType="TextBlock"
           x:Key="TitleText">
        <Setter Property="FontSize" Value="26"/>
        <Setter Property="Foreground">
            <Setter.Value>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Offset="0.0" Color="#90DDDD" />
                        <GradientStop Offset="1.0" Color="#5BFFFF" />
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<StackPanel>
    <TextBlock Style="{StaticResource TitleText}" Name="textblock1">My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

Dieser TextBlock-Stil ist nun zentriert und verwendet eine Comic Sans MS-Schriftart mit einer Größe von 26. Außerdem wird die Vordergrundfarbe, die auf LinearGradientBrush festgelegt ist, im Beispiel angezeigt. Beachten Sie, dass der FontSize-Wert des zugrunde liegenden Stils überschrieben wird. Wenn mehr als ein Setter-Objekt in einem Style-Objekt auf dieselbe Eigenschaft verweist, hat das zuletzt deklarierte Setter-Objekt Vorrang.

Im folgenden Screenshot wird gezeigt, wie die TextBlock-Elemente nun aussehen:

Styled TextBlocks

Dieser TitleText-Stil erweitert den Stil, der für den TextBlock-Typ erstellt wurde, auf den mit BasedOn="{StaticResource {x:Type TextBlock}}" verwiesen wird. Ein Stil mit einem x:Key-Attribut lässt sich auch mit dem x:Key-Wert des Stils erweitern. Wenn Sie z. B. einen Stil namens Header1 erweitern möchten, würden Sie BasedOn="{StaticResource Header1}" verwenden.

Beziehung zwischen der Eigenschaft „TargetType“ und dem Attribut „x:Key“

Wenn die Eigenschaft TargetType auf TextBlock festgelegt wird, ohne dem Stil ein x:Key-Attribut zuzuweisen, wird ein Stil, wie bereits gezeigt, auf alle TextBlock-Elemente angewendet. In diesem Fall wird x:Key implizit auf {x:Type TextBlock} festgelegt. Wenn Sie das Attribut x:Key also auf einen anderen Wert als {x:Type TextBlock} festlegen, wird Style nicht automatisch auf alle TextBlock-Elemente angewendet. Stattdessen müssen Sie den Stil (mithilfe des x:Key-Werts) auf die TextBlock-Elemente explizit anwenden. Wenn sich Ihr Stil im Ressourcenabschnitt befindet und Sie die Eigenschaft TargetType nicht für Ihren Stil festlegen, müssen Sie das Attribut x:Key festlegen.

Die Eigenschaft TargetType stellt nicht nur einen Standardwert für x:Key bereit, sondern gibt auch den Typ an, für den die Setter-Eigenschaften gelten. Wenn Sie TargetType nicht angeben, müssen Sie die Eigenschaften in den Setter-Objekten mit einem Klassennamen in der Syntax Property="ClassName.Property" qualifizieren. Anstatt beispielsweise Property="FontSize" festzulegen, müssen Sie Property auf "TextBlock.FontSize" oder "Control.FontSize" festlegen.

Beachten Sie außerdem, dass viele WPF-Steuerelemente aus einer Kombination anderer WPF-Steuerelementen bestehen. Wenn Sie einen Stil erstellen, das für alle Steuerelemente eines Typs gilt, erhalten Sie möglicherweise unerwartete Ergebnisse. Wenn Sie beispielsweise einen Stil für den TextBlock-Typ in einem Window-Objekt erstellen, wird der Stil auf alle TextBlock-Steuerelemente im Fenster angewendet, auch wenn TextBlock Teil eines anderen Steuerelements wie ListBox ist.

Siehe auch