Megosztás a következőn keresztül:


Sablon létrehozása vezérlőelemhez (WPF.NET)

A Windows Presentation Foundation (WPF) segítségével testre szabhatja egy meglévő vezérlő vizuális struktúráját és viselkedését saját újrafelhasználható sablonjával. A sablonok globálisan alkalmazhatók az alkalmazásra, az ablakokra és a lapokra, vagy közvetlenül a vezérlőkre. A legtöbb olyan forgatókönyv, amely új vezérlő létrehozását igényel, helyettesíthető egy új sablon létrehozásával egy meglévő vezérlőhöz.

Ebben a cikkben megismerkedhet azzal, hogyan hozhat létre egy új ControlTemplate-t a Button vezérlőelemhez.

Mikor hozzon létre ControlTemplate-et?

A vezérlők számos tulajdonsággal rendelkeznek, például Background, Foregroundés FontFamily. Ezek a tulajdonságok a vezérlő megjelenésének különböző aspektusait vezérli, de a tulajdonságok beállításával végrehajtott módosítások korlátozottak. Például beállíthatja a Foreground tulajdonságot kékre és a FontStyle-et dőltre egy CheckBox-n. Ha testre szeretné szabni a vezérlő megjelenését a vezérlő többi tulajdonságának beállításán túl, létre kell hoznia egy ControlTemplate.

A legtöbb felhasználói felületen a gomb általános megjelenése megegyezik: egy szöveggel ellátott téglalap. Ha lekerekített gombot szeretne létrehozni, létrehozhat egy új vezérlőt, amely örökli a gombot, vagy újra létrehozza a gomb funkcióit. Az új felhasználói vezérlő emellett körkörös vizualizációt is biztosít.

Egy meglévő vezérlő vizuális elrendezésének testreszabásával elkerülheti az új vezérlők létrehozását. Egy lekerekített gombbal létrehoz egy ControlTemplate a kívánt vizuális elrendezéssel.

Ha viszont új funkciókkal, különböző tulajdonságokkal és új beállításokkal rendelkező vezérlőre van szüksége, akkor létre kell hoznia egy új UserControl.

Előfeltételek

Hozzon létre egy új WPF-alkalmazást, és MainWindow.xaml (vagy egy másik választott ablakban) állítsa be a következő tulajdonságokat a <Ablak> elemen:

Ingatlan Érték
Title Template Intro Sample
SizeToContent WidthAndHeight
MinWidth 250

Állítsa a <Ablak> elem tartalmát a következő XAML-re:

<StackPanel Margin="10">
    <Label>Unstyled Button</Label>
    <Button>Button 1</Button>
    <Label>Rounded Button</Label>
    <Button>Button 2</Button>
</StackPanel>

Végül a MainWindow.xaml fájlnak az alábbiakhoz hasonlóan kell kinéznie:

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

Ha futtatja az alkalmazást, az a következőképpen néz ki:

WPF ablak két stílus nélküli gombbal

ControlTemplate létrehozása

A ControlTemplate deklarálása leggyakrabban erőforrásként történik egy XAML-fájl Resources szakaszában. Mivel a sablonok erőforrások, ugyanazokat a hatókörkezelési szabályokat betartják, amelyek az összes erőforrásra vonatkoznak. Egyszerűen fogalmazva, ahol a sablon deklarálása hatással van a sablon alkalmazhatóságára. Ha például az alkalmazásdefiníció XAML-fájljának gyökérelemében deklarálja a sablont, a sablon bárhol használható az alkalmazásban. Ha egy ablakban definiálja a sablont, csak az abban az ablakban lévő vezérlők használhatják a sablont.

Először is adjon hozzá egy Window.Resources elemet a MainWindow.xaml fájlhoz:

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

Hozzon létre egy új <ControlTemplate> a következő tulajdonságkészlettel:

Ingatlan Érték
x:Kulcs roundbutton
TargetType Button

Ez a vezérlősablon egyszerű lesz:

  • a vezérlő alapeleme, egy Grid
  • egy Ellipse a gomb lekerekített megjelenésének rajzolásához
  • egy ContentPresenter a felhasználó által megadott gombtartalom megjelenítéséhez
<ControlTemplate x:Key="roundbutton" TargetType="Button">
    <Grid>
        <Ellipse Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Grid>
</ControlTemplate>

Sablonkötés

Amikor egy új ControlTemplate-t hoz létre, érdemes lehet a vezérlő megjelenésének módosításához a nyilvános tulajdonságokat használni. A TemplateBinding jelölő nyelvi kiterjesztés egy olyan elem tulajdonságát köti össze a ControlTemplate-ban egy olyan nyilvános tulajdonsággal, amelyet a vezérlő definiált. Ha TemplateBindinghasznál, engedélyezheti, hogy a vezérlő tulajdonságai paraméterként működjenek a sablonban. Vagyis ha egy vezérlő egyik tulajdonsága be van állítva, a rendszer átadja az értéket annak az elemnek, amelyen a TemplateBinding található.

Ellipszis

Figyelje meg, hogy a Fill elem Stroke és < tulajdonságai a vezérlő > és tulajdonságaihoz vannak kötve.

Tartalombemutató

A <ContentPresenter> elem is hozzáadódik a sablonhoz. Mivel ez a sablon egy gombhoz készült, vegye figyelembe, hogy a gomb a ContentControltulajdonságait örökli. A gomb megjeleníti az elem tartalmát. A gombon belül bármit beállíthat, például egyszerű szöveget vagy egy másik vezérlőt. Az alábbiak közül mindkettő érvényes gomb:

<Button>My Text</Button>

<!-- and -->

<Button>
    <CheckBox>Checkbox in a button</CheckBox>
</Button>

Az előző példákban a szöveg és a jelölőnégyzet Button.Content tulajdonságként van beállítva. A tartalomként beállított tartalom egy <ContentPresenter>keresztül jelenik meg, ez a sablon feladata.

Ha a ControlTemplate egy ContentControl típusra, például egy Button-re, van alkalmazva, akkor a rendszer egy ContentPresenter-at keres az elemfában. Ha a ContentPresenter található, a sablon automatikusan a vezérlő Content tulajdonságát köti a ContentPresenter.

A sablon használata

Keresse meg a cikk elején deklarált gombokat.

<StackPanel Margin="10">
    <Label>Unstyled Button</Label>
    <Button>Button 1</Button>
    <Label>Rounded Button</Label>
    <Button>Button 2</Button>
</StackPanel>

Állítsa a második gomb Template tulajdonságát az roundbutton erőforrásra:

<StackPanel Margin="10">
    <Label>Unstyled Button</Label>
    <Button>Button 1</Button>
    <Label>Rounded Button</Label>
    <Button Template="{StaticResource roundbutton}">Button 2</Button>
</StackPanel>

Ha futtatja a projektet, és megtekinti az eredményt, látni fogja, hogy a gomb lekerekített háttérrel rendelkezik.

WPF ablak egy sablon ovális gombjával

Lehet, hogy észrevette, hogy a gomb nem kör, hanem ferde. Az <Ellipszis> elem működése miatt mindig kitágul, hogy kitöltse a rendelkezésre álló területet. A kör egységessé tétele a gomb width és height tulajdonságainak ugyanazzal az értékkel történő módosításával:

<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-ablak egy sablon körkörös gombjával

Eseményindító hozzáadása

Annak ellenére, hogy egy sablont tartalmazó gomb másképp néz ki, ugyanúgy viselkedik, mint bármely más gomb. Ha lenyomja a gombot, a Click esemény aktiválódik. Előfordulhat azonban, hogy amikor az egeret a gomb fölé viszi, a gomb vizualizációi nem változnak. Ezeket a vizualizációs interakciókat a sablon határozza meg.

A WPF által biztosított dinamikus esemény- és tulajdonságrendszerek segítségével megtekintheti egy adott érték adott tulajdonságát, majd szükség esetén átviheti a sablont. Ebben a példában a gomb IsMouseOver tulajdonságát fogja megtekinteni. Ha az egér a vezérlő felett van, formázza az <Ellipszis> új színnel. Ezt a típusú eseményindítót PropertyTriggernéven ismerjük.

Ahhoz, hogy ez működjön, meg kell adnia egy nevet a <Ellipszishez>, amelyre hivatkozhat. Adja meg backgroundElementnevét.

<Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />

Ezután adjon hozzá egy új Trigger a ControlTemplate.Triggers gyűjteményhez. Az eseményindító figyelni fogja a IsMouseOver eseményt a trueérték miatt.

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

Ezután adjon hozzá egy <Setter> a <Trigger>-hez, amely a < tulajdonságát új színre módosítja.

<Trigger Property="IsMouseOver" Value="true">
    <Setter Property="Fill" TargetName="backgroundElement" Value="AliceBlue"/>
</Trigger>

Futtassa a projektet. Figyelje meg, hogy amikor az egeret a gomb fölé viszi, a <Ellipszis> színe megváltozik.

ha az egér a WPF gombra halad, megváltozik a kitöltőszín

Használjon VisualState-et

A vizualizációs állapotokat egy vezérlő definiálja és aktiválja. Ha például az egér a vezérlő fölé kerül, a CommonStates.MouseOver állapot aktiválódik. A tulajdonságmódosításokat a vezérlő aktuális állapota alapján animálhatja. Az előző szakaszban egy <PropertyTrigger>-t használtak a gomb hátterének megváltoztatására AliceBlue-re, amikor a IsMouseOver tulajdonság trueállapotban volt. Ehelyett hozzon létre egy vizualizációs állapotot, amely animálja ennek a színnek a módosítását, zökkenőmentes átmenetet biztosítva. A VisualStatesStílusok és sablonok a WPFcímű témakörben talál további információt.

A <PropertyTrigger> animált vizualizációs állapottá alakításához először távolítsa el a <ControlTemplate.Triggers> elemet a sablonból.

<ControlTemplate x:Key="roundbutton" TargetType="Button">
    <Grid>
        <Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Grid>
</ControlTemplate>

Ezután a <Grid> vezérlősablon gyökerében adjon hozzá egy <VisualStateManager.VisualStateGroups> elemet, amely tartalmaz egy <VisualStateGroup> a CommonStatesszámára. Definiáljon két állapotot, Normal és 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>

A <VisualState> definiált animációk az adott állapot aktiválásakor lesznek alkalmazva. Animációk létrehozása az egyes állapotokhoz. Az animációk egy <storyboard> elembe kerülnek. További információ a storyboardokról: Storyboards Overview.

  • Normális

    Ez az állapot animálja az ellipszis kitöltését, és visszaállítja azt a vezérlőelem Background színére.

    <Storyboard>
        <ColorAnimation Storyboard.TargetName="backgroundElement" 
            Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
            To="{TemplateBinding Background}"
            Duration="0:0:0.3"/>
    </Storyboard>
    
  • Egérmutató

    Ez az állapot az ellipszis Background színét egy új színre animálja: Yellow.

    <Storyboard>
        <ColorAnimation Storyboard.TargetName="backgroundElement" 
            Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" 
            To="Yellow" 
            Duration="0:0:0.3"/>
    </Storyboard>
    

A <ControlTemplate> az alábbihoz hasonlóan kell kinéznie.

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

Futtassa a projektet. Figyelje meg, hogy amikor az egeret a gomb fölé viszi, a <Ellipszis> színe animáltan változik.

egér mozog a WPF gomb fölött, hogy megváltoztassa a kitöltő színt a vizuális állapottal

Következő lépések