Denetim için şablon oluşturma
Windows Presentation Foundation (WPF) ile mevcut bir denetimin görsel yapısını ve davranışını kendi yeniden kullanılabilir şablonunuzla özelleştirebilirsiniz. Şablonlar uygulamanıza, pencerelerinize ve sayfalarınıza genel olarak veya doğrudan denetimlere uygulanabilir. Yeni denetim oluşturmanızı gerektiren senaryoların çoğu, bunun yerine mevcut bir denetim için yeni bir şablon oluşturularak ele alınabilir.
Bu makalede, Button denetimi için yeni bir ControlTemplate nasıl oluşturacağınızı keşfedeceksiniz.
ControlTemplate ne zaman oluşturulur?
Denetimlerin Background, Foregroundve FontFamilygibi birçok özelliği vardır. Bu özellikler denetimin görünümünün farklı yönlerini denetler, ancak bu özellikleri ayarlayarak yapabileceğiniz değişiklikler sınırlıdır. Örneğin, CheckBoxüzerinde Foreground özelliğini mavi ve FontStyle'i italik olarak ayarlayabilirsiniz. Denetimin görünümünü, denetimdeki diğer özellikleri ayarlamanın yapabileceklerinin ötesinde özelleştirmek istediğinizde, bir ControlTemplateoluşturursunuz.
Çoğu kullanıcı arabiriminde, bir düğme aynı genel görünüme sahiptir: metin içeren bir dikdörtgen. Yuvarlak bir düğme oluşturmak istiyorsanız, düğmeden devralan veya düğmenin işlevselliğini yeniden oluşturan yeni bir denetim oluşturabilirsiniz. Buna ek olarak, yeni kullanıcı denetimi döngüsel görseli sağlar.
Mevcut bir denetimin görsel düzenini özelleştirerek yeni denetimler oluşturmaktan kaçınabilirsiniz. Yuvarlatılmış bir düğmeyle, istediğiniz görsel düzenine sahip bir ControlTemplate oluşturursunuz.
Öte yandan, yeni işlevlere, farklı özelliklere ve yeni ayarlara sahip bir denetime ihtiyacınız varsa, yeni bir UserControloluşturursunuz.
Önkoşullar
Yeni bir WPF uygulaması oluşturun ve MainWindow.xaml 'de (veya seçtiğiniz başka bir pencerede) <Window> öğesinde aşağıdaki özellikleri ayarlayın:
Mülk | Değer |
---|---|
Title | Template Intro Sample |
SizeToContent | WidthAndHeight |
MinWidth | 250 |
<Window> öğesinin içeriğini aşağıdaki XAML olarak ayarlayın:
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button>Button 2</Button>
</StackPanel>
Sonunda, MainWindow.xaml dosyası aşağıdakine benzer görünmelidir:
<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>
Uygulamayı çalıştırırsanız aşağıdaki gibi görünür:
WPF penceresi
ControlTemplate oluşturma
ControlTemplate bildirmenin en yaygın yolu, XAML dosyasının Resources
bölümünde bir kaynak olarak tanımlamaktır. Şablonlar kaynak olduğundan, tüm kaynaklar için geçerli olan aynı kapsam kurallarına uyarlar. Basitçe söylemek gerekirse, bir şablonu bildirdiğiniz yer, şablonun uygulanabileceği yeri etkiler. Örneğin, şablonu uygulama tanımı XAML dosyanızın kök öğesinde bildirirseniz, şablon uygulamanızın herhangi bir yerinde kullanılabilir. Şablonu bir pencerede tanımlarsanız, şablonu yalnızca bu penceredeki denetimler kullanabilir.
Başlangıç olarak, MainWindow.xaml dosyanıza bir Window.Resources
öğesi ekleyin:
<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>
Aşağıdaki özelliklerin ayarlandığı yeni bir <ControlTemplate> oluşturun:
Mülk | Değer |
---|---|
x:Key | roundbutton |
TargetType | Button |
Bu denetim şablonu basit olacaktır:
- Denetim için kök bir öğe, Grid
- Düğmenin yuvarlak görünümünü çizmek için Ellipse kullanın.
- Kullanıcının belirttiği düğme içeriğini görüntülemek için bir ContentPresenter oluşturun.
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<Ellipse Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
ŞablonBağlama
Yeni bir ControlTemplateoluşturduğunuzda, denetimin görünümünü değiştirmek için yine de genel özellikleri kullanmak isteyebilirsiniz.
TemplateBinding işaretleme uzantısı, ControlTemplate içindeki bir öğenin özelliğini denetim tarafından tanımlanan bir ortak özelliğe bağlar.
TemplateBindingkullandığınızda, denetimdeki özelliklerin şablona parametre olarak davranmasını sağlarsınız. Başka bir ifadeyle, denetimdeki bir özellik ayarlandığında, bu değer üzerinde templatebinding
Elips
<Elips> öğesinin Fill ve Stroke özelliklerinin denetimin Foreground ve Background özelliklerine bağlı olduğuna dikkat edin.
İçerik Sunucu
Şablona bir <ContentPresenter> öğesi de eklenir. Bu şablon bir düğme için tasarlandığından, düğmenin ContentControl'den devraldığını dikkate alın. düğme, öğesinin içeriğini gösterir. Düğmenin içinde düz metin ve hatta başka bir denetim gibi her şeyi ayarlayabilirsiniz. Aşağıdakilerin her ikisi de geçerli düğmelerdir:
<Button>My Text</Button>
<!-- and -->
<Button>
<CheckBox>Checkbox in a button</CheckBox>
</Button>
Önceki örneklerin her ikisinde de metin ve onay kutusu Button.Content özelliği olarak ayarlanmıştır. İçerik olarak ayarlanan her şey, şablonun yaptığı gibi <ContentPresenter>aracılığıyla sunulabilir.
ControlTemplate
Button
gibi bir ContentControl türüne uygulanırsa, öğe ağacında bir ContentPresenter aranılır.
ContentPresenter
bulunursa, şablon otomatik olarak denetimin Content özelliğini ContentPresenter
bağlar.
Şablonu kullanma
Bu makalenin başında bildirilen düğmeleri bulun.
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button>Button 2</Button>
</StackPanel>
İkinci düğmenin Template özelliğini roundbutton
kaynağına ayarlayın:
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button Template="{StaticResource roundbutton}">Button 2</Button>
</StackPanel>
Projeyi çalıştırır ve sonucuna bakarsanız düğmenin yuvarlatılmış bir arka planı olduğunu görürsünüz.
Düğmenin daire olmadığını ancak çarpık olduğunu fark etmiş olabilirsiniz. <Elips> öğesinin çalışma şekli nedeniyle, her zaman kullanılabilir alanı dolduracak şekilde genişler. Düğmenin width ve height özelliklerini aynı değerle değiştirerek dairenin tekdüzen olmasını sağlayın:
<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>
WPF penceresi
Tetikleyici Ekleme
Şablon uygulanmış bir düğme farklı görünse de, diğer tüm düğmelerle aynı şekilde davranır. Düğmeye basarsanız, Click olayı tetiklenir. Ancak farenizi düğmenin üzerine taşıdığınızda düğmenin görsellerinin değişmediğini fark etmiş olabilirsiniz. Bu görsel etkileşimlerin tümü şablon tarafından tanımlanır.
WPF'nin sağladığı dinamik olay ve özellik sistemleriyle, bir değer için belirli bir özelliği izleyebilir ve uygun olduğunda şablonu restyle yapabilirsiniz. Bu örnekte düğmenin IsMouseOver özelliğini izleyeceksiniz. Fare denetimin üzerindeyken, <Elips> yeni bir renkle şekillendirin. Bu tetikleyici türü, PropertyTriggerolarak bilinir.
Bunun işe yarayabilmesi için referans verebileceğiniz <Elips> bir ad eklemeniz gerekir. backgroundElementadını verin.
<Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
Ardından, ControlTemplate.Triggers koleksiyonuna yeni bir Trigger ekleyin. Tetikleyici, IsMouseOver
olayını true
değeri için izleyecek.
<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>
Ardından, <Üç Nokta>Dolgu özelliğini yeni bir renge değiştiren <Tetikleyicisi> bir <Ayarlayıcı> ekleyin.
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Fill" TargetName="backgroundElement" Value="AliceBlue"/>
</Trigger>
Projeyi çalıştırın. Fareyi düğmenin üzerine taşıdığınızda, <Elips> renginin değiştiğine dikkat edin.
Bir VisualState kullanın.
Görsel durumlar bir denetim tarafından tanımlanır ve tetiklenir. Örneğin, fare denetimin üzerine taşındığında CommonStates.MouseOver
durumu tetiklenir. Denetimin geçerli durumuna göre özellik değişikliklerine animasyon ekleyebilirsiniz. Önceki bölümde, IsMouseOver
özelliği true
olduğunda düğmenin öndeki rengini AliceBlue
'e değiştirmek için <PropertyTrigger> kullanıldı. Bunun yerine, bu rengin değişikliğine animasyon uygulayan ve sorunsuz bir geçiş sağlayan bir görsel durum oluşturun. VisualStates
<PropertyTrigger> animasyonlu görsel durumuna dönüştürmek için öncelikle <ControlTemplate.Triggers> öğesini şablonunuzdan kaldırın.
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
Ardından, denetim şablonunun Normal
ve MouseOver
iki durum tanımlayın.
<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>
<VisualState> tanımlanan animasyonlar, bu durum tetiklendiğinde uygulanır. Her durum için animasyonlar oluşturun. Animasyonlar bir <Görsel Taslak> öğesinin içine konur. Görsel taslaklar hakkında daha fazla bilgi için bkz. Görsel Taslaklara Genel Bakış.
Normal
Bu durum, elips dolgusunu canlandırır ve kontrolün
Background
rengine geri döndürür.<Storyboard> <ColorAnimation Storyboard.TargetName="backgroundElement" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="{TemplateBinding Background}" Duration="0:0:0.3"/> </Storyboard>
Fareyle Üzerine Gelme
Bu durum, elips
Background
rengini yeni bir renge animasyonla değiştirir:Yellow
.<Storyboard> <ColorAnimation Storyboard.TargetName="backgroundElement" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="Yellow" Duration="0:0:0.3"/> </Storyboard>
<ControlTemplate> artık aşağıdaki gibi görünmelidir.
<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>
Projeyi çalıştırın. Dikkat edin: Fareyi düğmenin üzerine taşıdığınızda, <Elipsin rengi> animasyonlu bir şekilde değişir.
Sonraki adımlar
.NET Desktop feedback