Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
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 mempelajari cara membuat ControlTemplate baru untuk kontrol Button.
Kapan membuat ControlTemplate
Kontrol memiliki banyak properti, seperti Background, Foreground, dan FontFamily. Properti ini mengontrol berbagai aspek tampilan kontrol, tetapi perubahan yang dapat Anda buat dengan mengatur properti ini terbatas. Misalnya, Anda dapat mengatur properti Foreground menjadi biru dan FontStyle menjadi miring pada elemen CheckBox. Ketika Anda ingin menyesuaikan tampilan kontrol lebih daripada yang dapat dilakukan oleh pengaturan properti lainnya 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 menyediakan visual melingkar.
Anda dapat menghindari pembuatan kontrol baru dengan menyesuaikan tata letak visual kontrol yang ada. Dengan tombol bulat, Anda membuat ControlTemplate dengan tata letak visual yang diinginkan.
Di sisi lain, jika Anda memerlukan kontrol dengan fungsionalitas baru, properti yang berbeda, dan pengaturan baru, Anda akan membuat UserControlbaru.
Prasyarat
Buat aplikasi WPF baru dan di
Harta benda | Nilai |
---|---|
Title | Template Intro Sample |
SizeToContent | WidthAndHeight |
MinWidth | 250 |
Atur konten elemen
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button>Button 2</Button>
</StackPanel>
Pada akhirnya, file
<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, tampilannya seperti 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, lokasi Anda mendeklarasikan templat akan mempengaruhi di mana templat tersebut 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 memulainya, tambahkan elemen
<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
Harta benda | Nilai |
---|---|
x:Kunci | roundbutton |
TargetType | Button |
Templat kontrol ini akan sederhana:
- sebuah elemen akar untuk kontrol, Grid
- Ellipse untuk menggambar tampilan tombol bulat
- 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 ControlTemplatebaru, Anda mungkin masih ingin menggunakan properti publik untuk mengubah tampilan kontrol. Ekstensi markup TemplateBinding
Ellipse
Perhatikan bahwa properti Fill dan Stroke dari elemen <Ellipse> terikat pada properti Foreground dan Background dari kontrol.
ContentPresenter
Elemen <ContentPresenter> juga ditambahkan ke templat. Karena templat ini dirancang untuk tombol, perhatikan bahwa tombol tersebut mewarisi properti 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 ditetapkan sebagai konten dapat disajikan melalui <ContentPresenter>, seperti yang dilakukan templat.
Jika ControlTemplate diterapkan ke jenis ContentControl, seperti Button
, ContentPresenter dicari di pohon elemen. Jika ContentPresenter
ditemukan, templat secara otomatis mengikat properti Content kontrol 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 Template tombol kedua ke sumber daya roundbutton
:
<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
<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 Click akan 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 sistem peristiwa dan properti dinamis yang disediakan WPF, Anda dapat memantau sebuah properti tertentu untuk nilai dan kemudian menggaya ulang pola ketika diperlukan. Dalam contoh ini, Anda akan mengawasi properti IsMouseOver dari tombol tersebut. 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. Beri nama backgroundElement.
<Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
Selanjutnya, tambahkan IsMouseOver
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 dari <Elips> dengan 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, status CommonStates.MouseOver
dipicu. Anda dapat menganimasikan perubahan properti berdasarkan status kontrol saat ini. Di bagian sebelumnya, < digunakan untuk mengubah latar belakang tombol menjadi > ketika properti adalah AliceBlue
.IsMouseOver
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
<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 templat kontrol Grid <>, 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 keadaan tersebut dipicu. Buat animasi untuk setiap status. Animasi dimasukkan ke dalam elemen Storyboard <>. Untuk informasi selengkapnya tentang papan cerita, lihat Gambaran Umum Storyboards.
Biasa
Keadaan ini menganimasikan warna isi elips, mengembalikannya ke warna
Background
dari kendali.<Storyboard> <ColorAnimation Storyboard.TargetName="backgroundElement" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="{TemplateBinding Background}" Duration="0:0:0.3"/> </Storyboard>
Gerakkan cursor ke atas (MouseOver)
Status ini menganimasikan warna
Background
elips ke warna baru:Yellow
.<Storyboard> <ColorAnimation Storyboard.TargetName="backgroundElement" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="Yellow" Duration="0:0:0.3"/> </Storyboard>
<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 ke atas tombol, warna <Elips> berubah.
Langkah selanjutnya
- Membuat gaya untuk kontrol
- Gaya dan templat
- Ringkasan sumber daya XAML
.NET Desktop feedback