Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Met Windows Presentation Foundation (WPF) kun je de visuele structuur en het gedrag van een bestaand besturingselement aanpassen met je eigen herbruikbare sjabloon. Sjablonen kunnen globaal worden toegepast op uw toepassing, vensters en pagina's of rechtstreeks op besturingselementen. In de meeste scenario's waarvoor u een nieuw besturingselement moet maken, kunt u in plaats daarvan een nieuwe sjabloon maken voor een bestaand besturingselement.
In dit artikel ontdekt u hoe u een nieuwe ControlTemplate voor de Button bediening maakt.
Wanneer maakt u een ControlTemplate
Besturingselementen hebben veel eigenschappen, zoals Background, Foregrounden FontFamily. Deze eigenschappen bepalen verschillende aspecten van het uiterlijk van het besturingselement, maar de wijzigingen die u kunt aanbrengen door deze eigenschappen in te stellen, zijn beperkt. U kunt de Foreground eigenschap bijvoorbeeld instellen op de kleur blauw en de stijl van FontStyle op cursief op een CheckBox. Als u het uiterlijk van het besturingselement wilt aanpassen dan wat de andere eigenschappen op het besturingselement kunnen doen, maakt u een ControlTemplate.
In de meeste gebruikersinterfaces heeft een knop dezelfde algemene weergave: een rechthoek met tekst. Als u een afgeronde knop wilt maken, kunt u een nieuw besturingselement maken die is gebaseerd op de knop of de functionaliteit van de knop nabootst. Daarnaast zou het nieuwe gebruikersbeheer de cirkelvormige visual bieden.
U kunt voorkomen dat er nieuwe besturingselementen worden gemaakt door de visuele indeling van een bestaand besturingselement aan te passen. Met een afgeronde knop maakt u een ControlTemplate met de gewenste visuele indeling.
Als u daarentegen een besturingselement met nieuwe functionaliteit, verschillende eigenschappen en nieuwe instellingen nodig hebt, maakt u een nieuwe UserControl.
Vereiste voorwaarden
Maak een nieuwe WPF-toepassing en stel in MainWindow.xaml (of een ander venster van uw keuze) de volgende eigenschappen in op het <vensterelement> :
| Vastgoed | Waarde |
|---|---|
| Title | Template Intro Sample |
| SizeToContent | WidthAndHeight |
| MinWidth | 250 |
Stel de inhoud van het <vensterelement> in op de volgende XAML:
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button>Button 2</Button>
</StackPanel>
Uiteindelijk moet het bestand MainWindow.xaml er ongeveer als volgt uitzien:
<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>
Als u de toepassing uitvoert, ziet deze er als volgt uit:
Een ControlTemplate maken
De meest voorkomende manier om een ControlTemplate te declareren is als een resource in de Resources sectie in een XAML-bestand. Omdat sjablonen resources zijn, voldoen ze aan dezelfde bereikregels die van toepassing zijn op alle resources. Simpel gezegd, waar een sjabloon wordt gedeclareerd beïnvloedt waar de sjabloon kan worden toegepast. Als u bijvoorbeeld de sjabloon declareert in het hoofdelement van het XAML-bestand van uw toepassingsdefinitie, kan de sjabloon overal in uw toepassing worden gebruikt. Als u de sjabloon in een venster definieert, kunnen alleen de besturingselementen in dat venster de sjabloon gebruiken.
Voeg eerst een Window.Resources element toe aan uw MainWindow.xaml-bestand :
<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>
Maak een nieuwe <ControlTemplate> met de volgende eigenschappen ingesteld:
| Vastgoed | Waarde |
|---|---|
| x:Sleutel | roundbutton |
| TargetType | Button |
Deze besturingselementsjabloon is eenvoudig:
- een hoofdelement voor het besturingselement, een Grid
- een Ellipse om het afgeronde uiterlijk van de knop te tekenen
- a ContentPresenter om de door de gebruiker opgegeven knopinhoud weer te geven
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<Ellipse Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
TemplateBinding
Wanneer u een nieuwe ControlTemplate maakt, wilt u mogelijk nog steeds de publieke eigenschappen gebruiken om het uiterlijk van de controle te wijzigen. De TemplateBinding-markeringsextensie verbindt een eigenschap van een element in de ControlTemplate aan een openbare eigenschap die is gedefinieerd door het besturingselement. Wanneer u een TemplateBinding gebruikt, stelt u eigenschappen op de control in om als parameters voor de sjabloon te fungeren. Wanneer een eigenschap voor een besturingselement is ingesteld, wordt die waarde doorgegeven aan het element met de TemplateBinding erop.
Ellips
U ziet dat de Fill en Stroke eigenschappen van het <Ellipse-element> afhankelijk zijn van de eigenschappen en Foreground eigenschappen van het besturingselementBackground.
ContentPresenter
Er wordt ook een <ContentPresenter-element> toegevoegd aan de sjabloon. Omdat deze sjabloon is ontworpen voor een knop, moet u er rekening mee houden dat de knop overneemt van ContentControl. De knop geeft de inhoud van het element weer. U kunt alles in de knop instellen, zoals tekst zonder opmaak of zelfs een ander besturingselement. Beide van de volgende zijn geldige knoppen:
<Button>My Text</Button>
<!-- and -->
<Button>
<CheckBox>Checkbox in a button</CheckBox>
</Button>
In beide vorige voorbeelden worden de tekst en het selectievakje ingesteld als de eigenschap Button.Content . Wat als inhoud is ingesteld, kan worden gepresenteerd via een <ContentPresenter>, wat de sjabloon doet.
Als het ControlTemplate wordt toegepast op een ContentControl type, zoals een Button, wordt er in de elementenboom naar ContentPresenter gezocht. Als de ContentPresenter wordt gevonden, wordt de Content-eigenschap automatisch aan het ContentPresenter gekoppeld.
De sjabloon gebruiken
Zoek de knoppen die aan het begin van dit artikel zijn gedeclareerd.
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button>Button 2</Button>
</StackPanel>
Stel de tweede knop met eigenschap Template in op de roundbutton resource.
<StackPanel Margin="10">
<Label>Unstyled Button</Label>
<Button>Button 1</Button>
<Label>Rounded Button</Label>
<Button Template="{StaticResource roundbutton}">Button 2</Button>
</StackPanel>
Als u het project uitvoert en het resultaat bekijkt, ziet u dat de knop een afgeronde achtergrond heeft.
U hebt misschien gemerkt dat de knop geen cirkel is, maar scheef is. Vanwege de manier waarop het <Ellipse-element> werkt, wordt het altijd uitgebreid om de beschikbare ruimte te vullen. Maak de cirkel uniform door de eigenschappen van de knop width en height te wijzigen naar dezelfde waarde.
<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>
Een trigger toevoegen
Hoewel een knop waarop een sjabloon is toegepast er anders uitziet, gedraagt deze zich hetzelfde als elke andere knop. Als u op de knop drukt, wordt de Click gebeurtenis geactiveerd. Het is echter mogelijk dat wanneer u de muisaanwijzer op de knop beweegt, de visuals van de knop niet veranderen. Deze visuele interacties worden allemaal gedefinieerd door de sjabloon.
Met de dynamische gebeurtenis- en eigenschapssystemen die WPF biedt, kunt u een specifieke eigenschap voor een waarde bekijken en vervolgens de sjabloon zo nodig opnieuw stylen. In dit voorbeeld bekijkt u de eigenschap van de knop IsMouseOver. Wanneer de muis boven het besturingselement staat, stijl de <Ellips> met een nieuwe kleur. Dit type trigger wordt een PropertyTrigger genoemd.
Hiervoor moet u een naam toevoegen aan de <ellips> waarnaar u kunt verwijzen. Geef deze de naam van backgroundElement.
<Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
Voeg vervolgens een nieuwe Trigger toe aan de verzameling ControlTemplate.Triggers . De trigger bekijkt de IsMouseOver gebeurtenis voor de waarde 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>
Voeg vervolgens een <Setter> toe aan de <Trigger> waarmee de eigenschap Opvulling van de <Ellipse> wordt gewijzigd in de gewenste kleur.
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Fill" TargetName="backgroundElement" Value="AliceBlue"/>
</Trigger>
Voer het project uit. U ziet dat wanneer u de muisaanwijzer over de knop beweegt, de kleur van het <beletselteken> verandert.
Een VisualState gebruiken
Visuele statussen worden gedefinieerd en geactiveerd door een besturingselement. Wanneer de muis bijvoorbeeld boven op het besturingselement wordt verplaatst, wordt de CommonStates.MouseOver toestand geactiveerd. U kunt wijzigingen van de eigenschap animeren op basis van de huidige status van het besturingselement. In de vorige sectie werd een <PropertyTrigger> gebruikt om de achtergrond van de knop te wijzigen in AliceBlue toen de IsMouseOver eigenschap was true. Maak in plaats daarvan een visuele status die de wijziging van deze kleur aangeeft, waardoor de overgang soepel verloopt. Zie Stijlen en sjablonen in WPF voor meer informatie over VisualStates.
Als u de <PropertyTrigger> wilt converteren naar een visuele animatiestatus, verwijdert u eerst het <element ControlTemplate.Triggers> uit de sjabloon.
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
Voeg vervolgens in de <Grid> van de controletemplate het <element VisualStateManager.VisualStateGroups> toe met een <VisualStateGroup> voor CommonStates. Definieer twee statussen, Normal en 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>
Animaties die in een <VisualState> zijn gedefinieerd, worden toegepast wanneer die status wordt geactiveerd. Animaties maken voor elke status. Animaties worden in een <Storyboard-element> geplaatst. Zie Storyboards Overviewvoor meer informatie over storyboards.
Normaal
Met deze status wordt de opvulling van het beletselteken gewijzigd en wordt deze terugzet naar de kleur van
Backgroundhet besturingselement.<Storyboard> <ColorAnimation Storyboard.TargetName="backgroundElement" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="{TemplateBinding Background}" Duration="0:0:0.3"/> </Storyboard>Muisovergang
Met deze status wordt de beletseltekenkleur
Backgroundaan een nieuwe kleur aangepast:Yellow.<Storyboard> <ColorAnimation Storyboard.TargetName="backgroundElement" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="Yellow" Duration="0:0:0.3"/> </Storyboard>
De <ControlTemplate> moet er nu als volgt uitzien.
<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>
Voer het project uit. U ziet dat wanneer u de muisaanwijzer over de knop beweegt, de kleur van het <beletselteken> animatie geeft.
Volgende stappen
.NET Desktop feedback