Vytvoření stylu ovládacího prvku (WPF .NET)

Pomocí windows Presentation Foundation (WPF) můžete přizpůsobit vzhled existujícího ovládacího prvku vlastním opakovaně použitelným stylem. Styly se dají použít globálně na vaši aplikaci, okna a stránky nebo přímo na ovládací prvky.

Důležité

Dokumentace k desktopové příručce pro .NET 7 a .NET 6 se právě připravuje.

Vytvoření stylu

Můžete si představit Style jako pohodlný způsob použití sady hodnot vlastností na jeden nebo více prvků. Styl můžete použít u libovolného prvku, který je odvozen nebo FrameworkElementFrameworkContentElement například WindowButton.

Nejběžnější způsob, jak deklarovat styl, je jako prostředek v Resources oddílu v souboru XAML. Vzhledem k tomu, že styly jsou prostředky, dodržují stejná pravidla oborů, která platí pro všechny prostředky. Jednoduše řečeno, kde deklarujete styl, má vliv na to, kde se styl dá použít. Pokud například deklarujete styl v kořenovém prvku souboru XAML definice aplikace, můžete styl použít kdekoli v aplikaci.

<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>

Pokud deklarujete styl v jednom ze souborů XAML aplikace, můžete tento styl použít jenom v daném souboru XAML. Další informace o pravidlech oborů pro prostředky najdete v tématu Přehled prostředků XAML.

<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>

Styl se skládá z podřízených <Setter> prvků, které nastavily vlastnosti prvků, na které je styl použit. V předchozím příkladu si všimněte, že styl je nastavený tak, aby se použil u TextBlock typů prostřednictvím atributu TargetType . Styl nastaví FontSize na 15 hodnotu a FontWeight na ExtraBoldhodnotu . <Setter> Přidejte pro každou vlastnost změnu stylu.

Implicitní použití stylu

A Style je pohodlný způsob, jak použít sadu hodnot vlastností na více než jeden prvek. Představte si například následující TextBlock prvky a jejich výchozí vzhled v okně.

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

Styling sample screenshot before

Výchozí vzhled můžete změnit nastavením vlastností, například FontSize a FontFamily, přímo u každého TextBlock prvku. Pokud ale chcete TextBlock , aby prvky sdílely některé vlastnosti, můžete vytvořit Style v Resources části souboru XAML, jak je znázorněno zde.

<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>

Když nastavíte TargetType styl na TextBlock typ a vynecháte x:Key atribut, styl se použije na všechny TextBlock prvky vymezené na styl, což je obecně samotný soubor XAML.

Teď se TextBlock prvky zobrazí následujícím způsobem.

Styling sample screenshot base style

Explicitní použití stylu

Pokud do stylu přidáte x:Key atribut s hodnotou, styl již není implicitně použit pro všechny prvky TargetType. Pouze prvky, které explicitně odkazují na styl, budou mít použitý styl.

Zde je styl z předchozí části, ale deklarován atributem x:Key .

<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>

Chcete-li použít styl, nastavte Style vlastnost prvku na x:Key hodnotu pomocí StaticResource rozšíření značek, jak je znázorněno zde.

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

Všimněte si, že první TextBlock prvek má použitý styl, zatímco druhý TextBlock element zůstane beze změny. Implicitní styl z předchozího oddílu byl změněn na styl, který deklaroval x:Key atribut, což znamená, že jediný prvek ovlivněný stylem je ten, který odkazoval přímo na styl.

Styling sample screenshot textblock

Jakmile se styl použije, explicitně nebo implicitně, zapečetí a nedá se změnit. Pokud chcete změnit použitý styl, vytvořte nový styl, který nahradí stávající styl. Další informace najdete v IsSealed této vlastnosti.

Můžete vytvořit objekt, který zvolí styl, který se použije na základě vlastní logiky. Příklad najdete v příkladu poskytnutém StyleSelector pro třídu.

Použití stylu prostřednictvím kódu programu

Pokud chcete k elementu přiřadit pojmenovaný styl programově, získejte styl z kolekce prostředků a přiřaďte ho k vlastnosti elementu Style . Položky v kolekci prostředků jsou typu Object. Proto je nutné přetypovat načtený styl na objekt System.Windows.Style před jeho přiřazením Style k vlastnosti. Například následující kód nastaví styl pojmenovaného TextBlocktextblock1 na definovaný styl TitleText.

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

Rozšíření stylu

Možná chcete, aby vaše dva TextBlock prvky sdílely některé hodnoty vlastností, jako FontFamily je například a na střed HorizontalAlignment. Ale také chcete, aby text Obrázky měl některé další vlastnosti. Můžete to udělat tak, že vytvoříte nový styl založený na prvním stylu, jak je znázorněno zde.

<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>

Tento TextBlock styl je nyní na střed, používá Comic Sans MS písmo s velikostí 26a barvu popředí nastavenou LinearGradientBrush na zobrazený v příkladu. Všimněte si, že přepíše FontSize hodnotu základního stylu. Pokud existuje více než jedna Setter odkazující na stejnou vlastnost v objektu Style, Setter má přednost ten, který je deklarován jako poslední.

Následující příklad ukazuje, TextBlock jak prvky teď vypadají:

Styled TextBlocks

Tento TitleText styl rozšiřuje styl vytvořený pro TextBlock typ, na který BasedOn="{StaticResource {x:Type TextBlock}}"odkazuje . Styl, který má x:Key styl, můžete také rozšířit pomocí x:Key stylu. Pokud byl například styl pojmenovaný Header1 a chtěli jste tento styl rozšířit, použili BasedOn="{StaticResource Header1}"byste .

Relace vlastnosti TargetType a atributu x:Key

Jak je znázorněno dříve, nastavení TargetType vlastnosti TextBlock bez přiřazení stylu x:Key způsobí použití stylu u všech TextBlock prvků. V tomto případě x:Key je implicitně nastaven na {x:Type TextBlock}. To znamená, že pokud explicitně nastavíte x:Key hodnotu na cokoli jiného než {x:Type TextBlock}, Style nepoužije se automaticky u všech TextBlock prvků. Místo toho musíte u prvků explicitně použít styl (pomocí x:Key hodnoty TextBlock ). Pokud je váš styl v oddílu prostředků a vlastnost ve stylu nenastavíte TargetType , musíte nastavit x:Key atribut.

Kromě poskytnutí výchozí hodnoty pro x:Key, TargetType vlastnost určuje typ, na který setter vlastnosti použít. Pokud nezadáte TargetType, musíte kvalifikovat vlastnosti v Setter objektech názvem třídy pomocí syntaxe Property="ClassName.Property". Například místo nastavení Property="FontSize"musíte nastavit Property nebo "TextBlock.FontSize""Control.FontSize".

Všimněte si také, že mnoho ovládacích prvků WPF se skládá z kombinace jiných ovládacích prvků WPF. Pokud vytvoříte styl, který se vztahuje na všechny ovládací prvky typu, může dojít k neočekávaným výsledkům. Pokud například vytvoříte styl, který cílí na TextBlock typ v Window, styl se použije na všechny TextBlock ovládací prvky v okně, i když TextBlock je součástí jiného ovládacího prvku, například ListBox.

Viz také