Cara membuat gaya untuk kontrol (WPF .NET)

Dengan Windows Presentation Foundation (WPF), Anda dapat menyesuaikan tampilan kontrol yang ada dengan gaya yang dapat digunakan kembali. Gaya dapat diterapkan secara global ke aplikasi, jendela, dan halaman Anda, atau langsung ke kontrol.

Penting

Dokumentasi Panduan Desktop untuk .NET 7 dan .NET 6 sedang dibangun.

Membuat gaya

Anda dapat menganggap Style sebagai cara mudah untuk menerapkan sekumpulan nilai properti ke satu atau beberapa elemen. Anda dapat menggunakan gaya pada elemen apa pun yang berasal dari FrameworkElement atau FrameworkContentElement seperti Window atau Button.

Cara paling umum untuk mendeklarasikan gaya adalah sebagai sumber daya di Resources bagian dalam file XAML. Karena gaya adalah sumber daya, gaya mematuhi aturan cakupan yang sama yang berlaku untuk semua sumber daya. Sederhananya, di mana Anda mendeklarasikan gaya memengaruhi di mana gaya dapat diterapkan. Misalnya, jika Anda mendeklarasikan gaya dalam elemen akar file XAML definisi aplikasi Anda, gaya dapat digunakan di mana saja di aplikasi Anda.

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

Jika Anda mendeklarasikan gaya dalam salah satu file XAML aplikasi, gaya hanya dapat digunakan dalam file XAML tersebut. Untuk informasi selengkapnya tentang aturan cakupan untuk sumber daya, lihat Gambaran Umum sumber daya 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>

Gaya terdiri dari elemen turunan <Setter> yang mengatur properti pada elemen tempat gaya diterapkan. Dalam contoh di atas, perhatikan bahwa gaya diatur untuk diterapkan ke TextBlock jenis melalui TargetType atribut . Gaya akan mengatur ke FontSize dan ke FontWeightExtraBold.15 <Setter> Tambahkan untuk setiap properti perubahan gaya.

Menerapkan gaya secara implisit

Adalah Style cara mudah untuk menerapkan sekumpulan nilai properti ke lebih dari satu elemen. Misalnya, pertimbangkan elemen berikut TextBlock dan tampilan defaultnya di jendela.

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

Styling sample screenshot before

Anda dapat mengubah tampilan default dengan mengatur properti, seperti FontSize dan FontFamily, pada setiap TextBlock elemen secara langsung. Namun, jika Anda ingin elemen Anda TextBlock berbagi beberapa properti, Anda dapat membuat di bagian Resources file XAML Anda, seperti yang Style ditunjukkan di sini.

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

Saat Anda mengatur TargetType gaya Anda ke TextBlock jenis dan menghilangkan x:Key atribut, gaya diterapkan ke semua TextBlock elemen yang dilingkupkan ke gaya, yang umumnya adalah file XAML itu sendiri.

TextBlock Sekarang elemen muncul sebagai berikut.

Styling sample screenshot base style

Menerapkan gaya secara eksplisit

Jika Anda menambahkan x:Key atribut dengan nilai ke gaya, gaya tidak lagi diterapkan secara implisit ke semua elemen TargetType. Hanya elemen yang secara eksplisit mereferensikan gaya yang akan memiliki gaya yang diterapkan padanya.

Berikut adalah gaya dari bagian sebelumnya, tetapi dinyatakan dengan x:Key atribut .

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

Untuk menerapkan gaya, atur Style properti pada elemen ke x:Key nilai , menggunakan ekstensi markup StaticResource, seperti yang ditunjukkan di sini.

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

Perhatikan bahwa elemen pertama TextBlock memiliki gaya yang diterapkan padanya sementara elemen TextBlock kedua tetap tidak berubah. Gaya implisit dari bagian sebelumnya diubah menjadi gaya yang mendeklarasikan x:Key atribut, artinya, satu-satunya elemen yang terpengaruh oleh gaya adalah yang mereferensikan gaya secara langsung.

Styling sample screenshot textblock

Setelah gaya diterapkan, secara eksplisit atau implisit, gaya akan disegel dan tidak dapat diubah. Jika Anda ingin mengubah gaya yang telah diterapkan, buat gaya baru untuk mengganti gaya yang sudah ada. Untuk informasi selengkapnya, lihat IsSealed properti.

Anda dapat membuat objek yang memilih gaya untuk diterapkan berdasarkan logika kustom. Misalnya, lihat contoh yang disediakan untuk StyleSelector kelas .

Menerapkan gaya secara terprogram

Untuk menetapkan gaya bernama ke elemen secara terprogram, dapatkan gaya dari koleksi sumber daya dan tetapkan ke properti elemen Style . Item dalam kumpulan sumber daya berjenis Object. Oleh karena itu, Anda harus melemparkan gaya yang System.Windows.Style diambil ke sebelum menetapkannya ke Style properti . Misalnya, kode berikut mengatur gaya bernama textblock1 ke gaya TitleTextyang TextBlock ditentukan .

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

Memperluas gaya

Mungkin Anda ingin dua TextBlock elemen Anda berbagi beberapa nilai properti, seperti FontFamily dan yang berpusat HorizontalAlignment. Tetapi Anda juga ingin teks Gambar Saya memiliki beberapa properti tambahan. Anda dapat melakukannya dengan membuat gaya baru yang didasarkan pada gaya pertama, seperti yang ditunjukkan di sini.

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

Gaya ini TextBlock sekarang berpusat Comic Sans MS , menggunakan font dengan ukuran 26, dan warna latar depan diatur ke yang LinearGradientBrush ditunjukkan dalam contoh. Perhatikan bahwa itu mengambil alih FontSize nilai gaya dasar. Jika ada lebih dari satu Setter yang menunjuk ke properti yang sama dalam Style, Setter yang dinyatakan terakhir diutamakan.

Berikut ini menunjukkan seperti apa TextBlock elemen sekarang:

Styled TextBlocks

Gaya ini TitleText memperluas gaya yang telah dibuat untuk jenis , yang direferensikan TextBlock dengan BasedOn="{StaticResource {x:Type TextBlock}}". Anda juga dapat memperluas gaya yang memiliki x:Key dengan menggunakan x:Key gaya. Misalnya, jika ada gaya bernama Header1 dan Anda ingin memperluas gaya itu, Anda akan menggunakan BasedOn="{StaticResource Header1}".

Hubungan properti TargetType dan atribut x:Key

Seperti yang ditunjukkan sebelumnya, mengatur TargetType properti ke TextBlock tanpa menetapkan gaya menyebabkan x:Key gaya diterapkan ke semua TextBlock elemen. Dalam hal ini, x:Key secara implisit diatur ke {x:Type TextBlock}. Ini berarti bahwa jika Anda secara eksplisit mengatur x:Key nilai ke apa pun selain {x:Type TextBlock}, Style tidak diterapkan ke semua TextBlock elemen secara otomatis. Sebagai gantinya, Anda harus menerapkan gaya (dengan menggunakan x:Key nilai ) ke TextBlock elemen secara eksplisit. Jika gaya Anda berada di bagian sumber daya dan Anda tidak mengatur TargetType properti pada gaya Anda, maka Anda harus mengatur x:Key atribut .

Selain memberikan nilai default untuk x:Key, TargetType properti menentukan jenis yang diterapkan properti setter. Jika Anda tidak menentukan TargetType, Anda harus memenuhi syarat properti di objek Anda Setter dengan nama kelas dengan menggunakan sintaks Property="ClassName.Property". Misalnya, alih-alih mengatur Property="FontSize", Anda harus mengatur Property ke "TextBlock.FontSize" atau "Control.FontSize".

Perhatikan juga bahwa banyak kontrol WPF terdiri dari kombinasi kontrol WPF lainnya. Jika Anda membuat gaya yang berlaku untuk semua kontrol jenis, Anda mungkin mendapatkan hasil yang tidak terduga. Misalnya, jika Anda membuat gaya yang menargetkan TextBlock jenis dalam Window, gaya diterapkan ke semua TextBlock kontrol di jendela, bahkan jika TextBlock adalah bagian dari kontrol lain, seperti ListBox.

Baca juga