Aracılığıyla paylaş


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 iki stilsiz düğme

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 olan öğeye geçirilir.

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 Buttongibi 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 ContentPresenterbağ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.

bir şablon oval düğmesiyle WPF penceresi

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 , bir şablon dairesel düğme ile

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ı truedeğ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.

fare imleci, dolgu rengini değiştirmek için WPF düğmesinin üzerine hareket eder

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 trueolduğ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. VisualStateshakkında daha fazla bilgi için, WPF'deki Stiller ve Şablonlara bakınız:.

<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 Grid kökünde için VisualStateGroup ile bir VisualStateManager.VisualStateGroups öğesini ekleyin. Normal ve MouseOveriki 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.

fare, WPF düğmesinin üzerinde hareket ederek görsel durumu değiştirmek

Sonraki adımlar