Membuat templat untuk kontrol
Dengan Windows Presentation Foundation (WPF), Anda dapat menyesuaikan struktur dan perilaku visual kontrol yang ada dengan templat anda sendiri yang dapat digunakan kembali. Templat dapat diterapkan secara global ke aplikasi, jendela, dan halaman Anda, atau langsung ke kontrol. Sebagian besar skenario yang mengharuskan Anda membuat kontrol baru dapat dicakup dengan membuat templat baru untuk kontrol yang sudah ada.
Dalam artikel ini, Anda akan menjelajahi pembuatan baru ControlTemplate untuk Button kontrol.
Kapan membuat ControlTemplate
Kontrol memiliki banyak properti, seperti Background, , Foregrounddan FontFamily. Properti ini mengontrol berbagai aspek tampilan kontrol, tetapi perubahan yang dapat Anda buat dengan mengatur properti ini terbatas. Misalnya, Anda dapat mengatur properti menjadi Foreground biru dan FontStyle miring pada CheckBox. Ketika Anda ingin menyesuaikan tampilan kontrol di luar pengaturan yang dapat dilakukan properti lain pada kontrol, Anda membuat ControlTemplate.
Di sebagian besar antarmuka pengguna, tombol memiliki tampilan umum yang sama: persegi panjang dengan beberapa teks. Jika Anda ingin membuat tombol bulat, Anda dapat membuat kontrol baru yang mewarisi dari tombol atau membuat ulang fungsionalitas tombol. Selain itu, kontrol pengguna baru akan memberikan visual melingkar.
Anda dapat menghindari pembuatan kontrol baru dengan menyesuaikan tata letak visual kontrol yang ada. Dengan tombol bulat, Anda membuat dengan tata letak visual yang ControlTemplate diinginkan.
Di sisi lain, jika Anda memerlukan kontrol dengan fungsionalitas baru, properti yang berbeda, dan pengaturan baru, Anda akan membuat baru UserControl.
Prasyarat
Buat aplikasi WPF baru dan di MainWindow.xaml (atau jendela lain pilihan Anda) atur properti berikut pada <elemen Window>:
Properti | Nilai |
---|---|
Title | Template Intro Sample |
SizeToContent | WidthAndHeight |
MinWidth | 250 |
Atur konten <elemen Window> ke XAML berikut:
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button>Button 2</Button>
</StackPanel>
Pada akhirnya, file MainWindow.xaml akan terlihat mirip dengan yang berikut ini:
<Window x:Class="IntroToStylingAndTemplating.Window1"
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="Template Intro Sample" SizeToContent="WidthAndHeight" MinWidth="250">
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button>Button 2</Button>
</StackPanel>
</Window>
Jika Anda menjalankan aplikasi, sepertinya berikut ini:
Membuat ControlTemplate
Cara paling umum untuk mendeklarasikan ControlTemplate adalah sebagai sumber daya di bagian Resources
dalam file XAML. Karena templat adalah sumber daya, templat mematuhi aturan cakupan yang sama yang berlaku untuk semua sumber daya. Sederhananya, di mana Anda mendeklarasikan templat memengaruhi tempat templat dapat diterapkan. Misalnya, jika Anda mendeklarasikan templat dalam elemen akar file XAML definisi aplikasi Anda, templat dapat digunakan di mana saja dalam aplikasi Anda. Jika Anda menentukan templat di jendela, hanya kontrol di jendela tersebut yang dapat menggunakan templat.
Untuk memulai, tambahkan Window.Resources
elemen ke file MainWindow.xaml Anda:
<Window x:Class="IntroToStylingAndTemplating.Window2"
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="Template Intro Sample" SizeToContent="WidthAndHeight" MinWidth="250">
<Window.Resources>
</Window.Resources>
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button>Button 2</Button>
</StackPanel>
</Window>
Buat ControlTemplate> baru <dengan kumpulan properti berikut:
Properti | Nilai |
---|---|
x:Kunci | roundbutton |
TargetType | Button |
Templat kontrol ini akan sederhana:
- elemen akar untuk kontrol, a Grid
- untuk Ellipse menggambar tampilan bulat tombol
- ContentPresenter untuk menampilkan konten tombol yang ditentukan pengguna
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<Ellipse Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
Pengikatan Templat
Saat membuat baru ControlTemplate, Anda mungkin masih ingin menggunakan properti publik untuk mengubah tampilan kontrol. Ekstensi markup TemplateBinding mengikat properti elemen yang ada di ControlTemplate properti publik yang ditentukan oleh kontrol. Saat Anda menggunakan TemplateBinding, Anda mengaktifkan properti pada kontrol untuk bertindak sebagai parameter ke templat. Artinya, ketika properti pada kontrol diatur, nilai tersebut diteruskan ke elemen yang memiliki TemplateBinding di atasnya.
Ellipse
Perhatikan bahwa Fill properti dan Stroke elemen< Elips> terikat ke properti dan Background kontrolForeground.
ContentPresenter
Elemen <ContentPresenter> juga ditambahkan ke templat. Karena templat ini dirancang untuk tombol, pertimbangkan bahwa tombol mewarisi dari ContentControl. Tombol menyajikan konten elemen . Anda dapat mengatur apa pun di dalam tombol, seperti teks biasa atau bahkan kontrol lain. Kedua tombol berikut ini adalah tombol yang valid:
<Button>My Text</Button>
<!-- and -->
<Button>
<CheckBox>Checkbox in a button</CheckBox>
</Button>
Dalam kedua contoh sebelumnya, teks dan kotak centang diatur sebagai properti Button.Content . Apa pun yang diatur sebagai konten dapat disajikan melalui <ContentPresenter>, yang merupakan apa yang dilakukan templat.
ControlTemplate Jika diterapkan ke ContentControl jenis, seperti Button
, dicari ContentPresenter di pohon elemen. ContentPresenter
Jika ditemukan, templat secara otomatis mengikat properti kontrol Content ke ContentPresenter
.
Menggunakan templat
Temukan tombol yang dideklarasikan di awal artikel ini.
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button>Button 2</Button>
</StackPanel>
Atur properti tombol Template kedua ke roundbutton
sumber daya:
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button Template="{StaticResource roundbutton}">Button 2</Button>
</StackPanel>
Jika Anda menjalankan proyek dan melihat hasilnya, Anda akan melihat bahwa tombol memiliki latar belakang bulat.
Anda mungkin telah memperhatikan bahwa tombol tersebut bukan lingkaran tetapi condong. Karena cara <kerja elemen Elips, elemen Elips> selalu berkembang untuk mengisi ruang yang tersedia. Buat lingkaran seragam dengan mengubah properti dan height tombol width ke nilai yang sama:
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button Template="{StaticResource roundbutton}" Width="65" Height="65">Button 2</Button>
</StackPanel>
Menambahkan Pemicu
Meskipun tombol dengan templat yang diterapkan terlihat berbeda, tombol tersebut berfungsi sama dengan tombol lainnya. Jika Anda menekan tombol , peristiwa akan Click diaktifkan. Namun, Anda mungkin telah memperhatikan bahwa ketika Anda menggerakkan mouse Anda di atas tombol, visual tombol tidak berubah. Interaksi visual ini semuanya ditentukan oleh templat.
Dengan peristiwa dinamis dan sistem properti yang disediakan WPF, Anda dapat menonton properti tertentu untuk nilai dan kemudian memulihkan templat jika sesuai. Dalam contoh ini, Anda akan menonton properti tombol IsMouseOver . Ketika mouse berada di atas kontrol, gaya <Elips> dengan warna baru. Jenis pemicu ini dikenal sebagai PropertyTrigger.
Agar ini berfungsi, Anda harus menambahkan nama ke <Elips> yang dapat Anda referensikan. Berikan nama backgroundElement.
<Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
Selanjutnya, tambahkan baru Trigger ke koleksi ControlTemplate.Triggers . Pemicu akan menonton IsMouseOver
peristiwa untuk nilai true
.
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Selanjutnya, tambahkan Setter ><ke <Pemicu> yang mengubah properti Isian < Elips> ke warna baru.
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Fill" TargetName="backgroundElement" Value="AliceBlue"/>
</Trigger>
Jalankan proyek. Perhatikan bahwa ketika Anda menggerakkan mouse di atas tombol, warna <Elips> berubah.
Menggunakan VisualState
Status visual ditentukan dan dipicu oleh kontrol. Misalnya, ketika mouse dipindahkan di atas kontrol, CommonStates.MouseOver
status dipicu. Anda dapat menganimasikan perubahan properti berdasarkan status kontrol saat ini. Di bagian sebelumnya, PropertyTrigger> digunakan untuk mengubah latar depan tombol menjadi AliceBlue
ketika IsMouseOver
properti adalah true
.< Sebagai gantinya, buat status visual yang menganimasikan perubahan warna ini, memberikan transisi yang lancar. Untuk informasi selengkapnya tentang VisualStates, lihat Gaya dan templat di WPF.
Untuk mengonversi PropertyTrigger> ke status visual animasi, Pertama, hapus <elemen ControlTemplate.Triggers> dari templat Anda.<
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
Selanjutnya, di akar Kisi> templat kontrol, tambahkan< elemen VisualStateManager.VisualStateGroups> dengan <VisualStateGroup> untuk CommonStates
.< Tentukan dua status, Normal
dan MouseOver
.
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal">
</VisualState>
<VisualState Name="MouseOver">
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
Animasi apa pun yang ditentukan dalam <VisualState> diterapkan saat status tersebut dipicu. Buat animasi untuk setiap status. Animasi dimasukkan ke <dalam elemen Storyboard> . Untuk informasi selengkapnya tentang papan cerita, lihat Gambaran Umum Papan Cerita.
Normal
Status ini menganimasikan isi elips, memulihkannya ke warna kontrol
Background
.<Storyboard> <ColorAnimation Storyboard.TargetName="backgroundElement" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="{TemplateBinding Background}" Duration="0:0:0.3"/> </Storyboard>
MouseOver
Status ini menganimasikan warna elips
Background
ke warna baru:Yellow
.<Storyboard> <ColorAnimation Storyboard.TargetName="backgroundElement" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="Yellow" Duration="0:0:0.3"/> </Storyboard>
<ControlTemplate> sekarang akan terlihat seperti berikut ini.
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal">
<Storyboard>
<ColorAnimation Storyboard.TargetName="backgroundElement"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
To="{TemplateBinding Background}"
Duration="0:0:0.3"/>
</Storyboard>
</VisualState>
<VisualState Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="backgroundElement"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
To="Yellow"
Duration="0:0:0.3"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Ellipse Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
<ContentPresenter x:Name="contentPresenter" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
Jalankan proyek. Perhatikan bahwa ketika Anda menggerakkan mouse di atas tombol, warna <elips> menganimasikan.
Langkah berikutnya
.NET Desktop feedback