Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of mappen te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen om mappen te wijzigen.
In dit artikel worden de functies van de XAML-taal beschreven en wordt gedemonstreerde hoe u XAML kunt gebruiken om WPF-apps (Windows Presentation Foundation) te schrijven. In dit artikel wordt specifiek XAML beschreven, zoals geïmplementeerd door WPF. XAML zelf is een groter taalconcept dan WPF.
Wat is XAML?
XAML is een declaratieve opmaaktaal. Zoals toegepast op het .NET-programmeermodel, vereenvoudigt XAML het maken van een gebruikersinterface voor een .NET-app. U kunt zichtbare UI-elementen maken in de declaratieve XAML-opmaak en vervolgens de UI-definitie scheiden van de runtimelogica met behulp van code-behind-bestanden die zijn gekoppeld aan de markering via gedeeltelijke klassedefinities. XAML vertegenwoordigt rechtstreeks de instantiëring van objecten in een specifieke set achterliggende typen die zijn gedefinieerd in assemblies. Dit is in tegenstelling tot de meeste andere opmaaktalen, die doorgaans een geïnterpreteerde taal zijn zonder een dergelijke directe koppeling naar een systeem van het backingtype. XAML maakt een werkstroom mogelijk waarin afzonderlijke partijen kunnen werken aan de gebruikersinterface en de logica van een app, met behulp van mogelijk verschillende hulpprogramma's.
Wanneer ze worden weergegeven als tekst, zijn XAML-bestanden XML-bestanden die over het algemeen de .xaml
extensie hebben. De bestanden kunnen worden gecodeerd door elke XML-codering, maar codering als UTF-8 is gebruikelijk.
In het volgende voorbeeld ziet u hoe u een knop kunt maken als onderdeel van een gebruikersinterface. Dit voorbeeld is bedoeld om u een beeld te geven van hoe XAML algemene metaforen voor ui-programmering vertegenwoordigt (dit is geen volledig voorbeeld).
<StackPanel>
<Button Content="Click Me"/>
</StackPanel>
XAML-syntaxis in het kort
In de volgende secties worden de basisvormen van de XAML-syntaxis uitgelegd en wordt een kort voorbeeld van markeringen weergegeven. Deze gedeelten zijn niet bedoeld om volledige informatie te geven over elke syntaxvorm, zoals hoe deze worden weergegeven in het achterliggende typesysteem. Zie XAML-syntaxis in detail voor meer informatie over de specifieke kenmerken van de XAML-syntaxis.
Veel van het materiaal in de volgende secties is elementair voor u als u eerder bekend bent met de XML-taal. Dit is een gevolg van een van de basisprincipes van XAML. De XAML-taal definieert concepten van zichzelf, maar deze concepten werken binnen de XML-taal en opmaakformulier.
XAML-objectelementen
Een objectelement declareert doorgaans een exemplaar van een type. Dit type wordt gedefinieerd in de assembly's waarnaar wordt verwezen door de technologie die XAML als taal gebruikt.
De syntaxis van het objectelement begint altijd met een openingshaakje (<
). Dit wordt gevolgd door de naam van het type waarin u een instantie wilt creëren. (De naam kan een voorvoegsel bevatten, een concept dat later wordt uitgelegd.) Hierna kunt u desgewenst kenmerken voor het objectelement declareren. Om de objectelementtag te voltooien, sluit af met een sluitende hoekhaak (>
). U kunt in plaats daarvan een zelfsluitende tag gebruiken die geen inhoud heeft, door de tag te voltooien met een schuine streep en sluitende hoek haak direct achter elkaar (/>
). Bekijk bijvoorbeeld het eerder getoonde markeringsfragment opnieuw.
<StackPanel>
<Button Content="Click Me"/>
</StackPanel>
Hiermee worden twee objectelementen opgegeven: <StackPanel>
(met inhoud en een afsluitende tag later) en <Button .../>
(het zelfsluitformulier, met verschillende kenmerken). De objectelementen StackPanel
en Button
komen overeen met de naam van een klasse die is gedefinieerd door WPF en maken deel uit van de WPF-assemblies. Wanneer u een objectelementtag opgeeft, maakt u een instructie voor XAML-verwerking om een nieuw exemplaar van het onderliggende type te maken. Elk exemplaar wordt gemaakt door de parameterloze constructor van het onderliggende type aan te roepen bij het parseren en laden van de XAML.
Kenmerksyntaxis (eigenschappen)
Eigenschappen van een object kunnen vaak worden uitgedrukt als kenmerken van het objectelement. De kenmerksyntaxis noemt de objecteigenschap die wordt ingesteld, gevolgd door de toewijzingsoperator (=). De waarde van een kenmerk wordt altijd opgegeven als een tekenreeks die tussen aanhalingstekens staat.
Kenmerksyntaxis is de meest gestroomlijnde syntaxis voor het instellen van eigenschappen en is de meest intuïtieve syntaxis voor ontwikkelaars die in het verleden opmaaktalen hebben gebruikt. Met de volgende markeringen wordt bijvoorbeeld een knop gemaakt met rode tekst en een blauwe achtergrond met een weergavetekst van Content
.
<Button Background="Blue" Foreground="Red" Content="This is a button"/>
Syntaxis van eigenschapselement
Voor sommige eigenschappen van een objectelement is de syntaxis van het kenmerk niet mogelijk, omdat het object of de informatie die nodig is om de eigenschapswaarde op te geven niet voldoende kan worden uitgedrukt in het aanhalingsteken en de tekenreeksbeperkingen van de kenmerksyntaxis. In deze gevallen kan een andere syntaxis, ook wel eigenschapselementsyntaxis genoemd, worden gebruikt.
De syntaxis voor de starttag van het eigenschapselement is <TypeName.PropertyName>
. Over het algemeen is de inhoud van die tag een objectelement van het type dat de eigenschap als waarde aanneemt. Nadat u de inhoud hebt opgegeven, moet u het eigenschapselement sluiten met een eindtag. De syntaxis voor de eindtag is </TypeName.PropertyName>
.
Als een kenmerksyntaxis mogelijk is, is het gebruik van de kenmerksyntaxis meestal handiger en maakt een compactere markering mogelijk, maar dat is vaak slechts een kwestie van stijl, niet een technische beperking. In het volgende voorbeeld ziet u dezelfde eigenschappen die worden ingesteld als in het vorige syntaxisvoorbeeld van het kenmerk, maar deze keer met behulp van de syntaxis van het eigenschapselement voor alle eigenschappen van de Button
.
<Button>
<Button.Background>
<SolidColorBrush Color="Blue"/>
</Button.Background>
<Button.Foreground>
<SolidColorBrush Color="Red"/>
</Button.Foreground>
<Button.Content>
This is a button
</Button.Content>
</Button>
Verzamelingssyntaxis
De XAML-taal bevat enkele optimalisaties die meer leesbare markeringen produceren. Een dergelijke optimalisatie is dat als een bepaalde eigenschap een verzamelingstype gebruikt, items die u in markeringen declareert als onderliggende elementen binnen de waarde van die eigenschap deel uitmaken van de verzameling. In dit geval is een verzameling onderliggende objectelementen de waarde die wordt ingesteld op de verzamelingseigenschap.
In het volgende voorbeeld ziet u de verzamelingssyntaxis voor het instellen van waarden van de GradientStops eigenschap.
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<!-- no explicit new GradientStopCollection, parser knows how to find or create -->
<GradientStop Offset="0.0" Color="Red" />
<GradientStop Offset="1.0" Color="Blue" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
XAML-inhoudseigenschappen
XAML geeft een taalfunctie op waarbij een klasse precies een van de eigenschappen kan aanwijzen als de inhoudseigenschap XAML. Onderliggende elementen van dat objectelement worden gebruikt om de waarde van die inhoudseigenschap in te stellen. Met andere woorden, voor de inhoudseigenschap kunt u een eigenschapselement weglaten bij het instellen van die eigenschap in XAML-markeringen en een meer zichtbare bovenliggende/onderliggende metafoor in de markering produceren.
Hiermee geeft u bijvoorbeeld Border een inhoudseigenschap van Child. De volgende twee Border elementen worden identiek behandeld. De eerste maakt gebruik van de syntaxis van de inhoudseigenschap en laat het Border.Child
eigenschapselement weg. De tweede toont expliciet Border.Child
.
<Border>
<TextBox Width="300"/>
</Border>
<!--explicit equivalent-->
<Border>
<Border.Child>
<TextBox Width="300"/>
</Border.Child>
</Border>
In de regel van de XAML-taal moet de waarde van een XAML-inhoudseigenschap geheel vóór of volledig na andere eigenschapselementen op dat objectelement worden gegeven. De volgende markeringen worden bijvoorbeeld niet gecompileerd.
<Button>I am a
<Button.Background>Blue</Button.Background>
blue button</Button>
Zie XAML-syntaxis in detail voor meer informatie over de specifieke kenmerken van de XAML-syntaxis.
Tekstinhoud
Een klein aantal XAML-elementen kan tekst rechtstreeks verwerken als inhoud. Als u dit wilt inschakelen, moet een van de volgende gevallen waar zijn:
De klasse moet een inhoudseigenschap declareren en die inhoudseigenschap moet van een type zijn dat kan worden toegewezen aan een tekenreeks (het type kan zijn Object). Elk ContentControl gebruikt Content als inhoudseigenschap en heeft het type Object, en dit ondersteunt het volgende gebruik op een ContentControl, zoals een Button:
<Button>Hello</Button>
.Het type moet een typeconversieprogramma declareren. In dat geval wordt de tekstinhoud gebruikt als initialisatietekst voor dat typeconversieprogramma. Bijvoorbeeld,
<Brush>Blue</Brush>
zet de inhoudswaarde vanBlue
om in een kwast. Dit geval is in de praktijk minder gebruikelijk.Het type moet een bekende XAML-taalprimitief zijn.
Gecombineerde inhoudseigenschappen en verzamelingssyntaxis
Bekijk dit voorbeeld.
<StackPanel>
<Button>First Button</Button>
<Button>Second Button</Button>
</StackPanel>
Hier is elk Button een onderliggend element van StackPanel. Dit is een gestroomlijnde en intuïtieve markering die twee tags om twee verschillende redenen weglaat.
Weggelaten eigenschapselement StackPanel.Children:StackPanel afgeleid van Panel. Panel definieert Panel.Children als de XAML-inhoudseigenschap.
Weggelaten UIElementCollection-objectelement: De Panel.Children eigenschap neemt het type UIElementCollection, dat implementeert IList. De elementtag van de verzameling kan worden weggelaten op basis van de XAML-regels voor het verwerken van verzamelingen, zoals IList. (In dit geval kan UIElementCollection niet worden geïnstantieerd, omdat het geen parameterloze constructor heeft, en daarom wordt het UIElementCollection objectelement als commentaar weergegeven).
<StackPanel>
<StackPanel.Children>
<!--<UIElementCollection>-->
<Button>First Button</Button>
<Button>Second Button</Button>
<!--</UIElementCollection>-->
</StackPanel.Children>
</StackPanel>
Kenmerksyntaxis (gebeurtenissen)
De syntaxis van het kenmerk kan ook worden gebruikt voor leden die gebeurtenissen zijn in plaats van eigenschappen. In dit geval is de naam van het kenmerk de naam van de gebeurtenis. In de WPF-implementatie van gebeurtenissen voor XAML is de waarde van het kenmerk de naam van een handler die de gedelegeerde van die gebeurtenis implementeert. Met de volgende markup wordt bijvoorbeeld een handler voor de Click gebeurtenis toegewezen aan een Button die in markup is gemaakt.
<Button Click="Button_Click" >Click Me!</Button>
Er zijn meer gebeurtenissen en XAML in WPF dan alleen dit voorbeeld van de syntaxis van het kenmerk. U vraagt zich bijvoorbeeld af wat de ClickHandler
verwijzing hier vertegenwoordigt en hoe deze is gedefinieerd. Dit wordt uitgelegd in de komende gebeurtenissen en de XAML-code-behind van dit artikel.
Hoofdletters en witruimte in XAML
Over het algemeen is XAML hoofdlettergevoelig. Voor het oplossen van backingtypen is WPF XAML hoofdlettergevoelig volgens dezelfde regels als de CLR hoofdlettergevoelig is. Objectelementen, eigenschapselementen en kenmerknamen moeten allemaal worden opgegeven met behulp van de gevoelige behuizing wanneer deze worden vergeleken met de naam van het onderliggende type in de assembly of aan een lid van een type. XAML-taaltrefwoorden en primitieven zijn ook hoofdlettergevoelig. Waarden zijn niet altijd hoofdlettergevoelig. Hoofdlettergevoeligheid voor waarden is afhankelijk van het gedrag van het type conversieprogramma dat is gekoppeld aan de eigenschap die de waarde gebruikt of het eigenschapswaardetype. Eigenschappen die het Boolean type aannemen, kunnen bijvoorbeeld een true
of True
gelijkwaardige waarden aannemen, maar alleen omdat de systeemeigen WPF XAML-parsertypeconversie voor tekenreeks Boolean deze al toestaat als equivalenten.
WPF XAML-processors en serializers negeren of verwijderen alle niet-significante witruimte en normaliseren elke significante witruimte. Dit is consistent met de standaard aanbevelingen voor witruimtegedrag van de XAML-specificatie. Dit gedrag is alleen van gevolg wanneer u tekenreeksen opgeeft binnen XAML-inhoudseigenschappen. In de eenvoudigste termen converteert XAML spaties, linefeed en tabtekens naar spaties en behoudt u één spatie als deze aan beide uiteinden van een aaneengesloten tekenreeks wordt gevonden. De volledige uitleg van de XAML-verwerking van witruimte wordt niet behandeld in dit artikel. Zie Witruimteverwerking in XAML voor meer informatie.
Opmaaksuitbreidingen
Markup-extensies zijn een XAML-taalconcept. Wanneer ze worden gebruikt om de waarde van een attributensyntaxis op te geven, geven accolades ({
en }
) het gebruik van een markup-extensie aan. Met dit gebruik wordt de XAML-verwerking om te ontsnappen aan de algemene behandeling van kenmerkwaarden als een letterlijke tekenreeks of een waarde voor het converteren van tekenreeksen.
De meest voorkomende markup-extensies die worden gebruikt in WPF-app-programmering zijn Binding
, gebruikt voor gegevensbindingsexpressies, en de resourceverwijzingen StaticResource
en DynamicResource
. Met behulp van markeringsextensies kunt u kenmerksyntaxis gebruiken om waarden voor eigenschappen op te geven, zelfs als die eigenschap geen ondersteuning biedt voor een kenmerksyntaxis in het algemeen. Markeringsextensies gebruiken vaak tussenliggende expressietypen om functies in te schakelen, zoals het uitstellen van waarden of het verwijzen naar andere objecten die alleen aanwezig zijn tijdens runtime.
Met de volgende markeringen wordt bijvoorbeeld de waarde van de Style eigenschap ingesteld met behulp van de syntaxis van het kenmerk. De Style eigenschap maakt gebruik van een exemplaar van de Style klasse, dat standaard niet kan worden geïnstantieerd door een tekenreeks voor de syntaxis van een kenmerk. Maar in dit geval verwijst het kenmerk naar een bepaalde markeringsextensie, StaticResource
. Wanneer deze markeringsextensie wordt verwerkt, wordt er een verwijzing geretourneerd naar een stijl die eerder is geïnstantieerd als een sleutelresource in een resourcewoordenlijst.
<Window x:Class="index.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="100" Width="300">
<Window.Resources>
<SolidColorBrush x:Key="MyBrush" Color="Gold"/>
<Style TargetType="Border" x:Key="PageBackground">
<Setter Property="BorderBrush" Value="Blue"/>
<Setter Property="BorderThickness" Value="5" />
</Style>
</Window.Resources>
<Border Style="{StaticResource PageBackground}">
<StackPanel>
<TextBlock Text="Hello" />
</StackPanel>
</Border>
</Window>
Zie WPF XAML Extensions voor een overzicht van alle markeringsextensies voor XAML die specifiek in WPF zijn geïmplementeerd. Zie XAML-naamruimte (x:) Taalfuncties voor XAML voor een overzicht van de markeringsextensies die zijn gedefinieerd door System.Xaml en die breder beschikbaar zijn voor .NET XAML-implementaties. Zie Markup Extensions en WPF XAML voor meer informatie over concepten van markeringsuitbreidingen.
Typeconverters
In de XAML-syntaxis in korte sectie is aangegeven dat de kenmerkwaarde moet kunnen worden ingesteld door een tekenreeks. De eenvoudige, systeemeigen verwerking van de manier waarop tekenreeksen worden geconverteerd naar andere objecttypen of primitieve waarden, is gebaseerd op het String type zelf, samen met systeemeigen verwerking voor bepaalde typen, zoals DateTime of Uri. Maar veel WPF-typen of leden van deze typen breiden het verwerkingsgedrag van het basistekenreekskenmerk zo uit dat exemplaren van complexere objecttypen kunnen worden opgegeven als tekenreeksen en kenmerken.
De Thickness structuur is een voorbeeld van een type waarvoor een typeconversie is ingeschakeld voor XAML-gebruik. Thickness geeft de metingen binnen een geneste rechthoek aan en wordt gebruikt als de waarde voor eigenschappen zoals Margin. Door een typeconversieprogramma in Thicknesste stellen, zijn alle eigenschappen die een Thickness gebruiken gemakkelijker op te geven in XAML, omdat ze kunnen worden opgegeven als kenmerken. In het volgende voorbeeld worden een typeconversie en kenmerksyntaxis gebruikt om een waarde voor een Margin te bieden.
<Button Margin="10,20,10,30" Content="Click me"/>
Het vorige voorbeeld van de syntaxis van het kenmerk is gelijk aan het volgende uitgebreidere syntaxisvoorbeeld, waarin het Margin in plaats daarvan wordt ingesteld via de syntaxis van het eigenschapselement dat een Thickness objectelement bevat. De vier belangrijkste eigenschappen van Thickness zijn ingesteld als kenmerken op het nieuwe exemplaar:
<Button Content="Click me">
<Button.Margin>
<Thickness Left="10" Top="20" Right="10" Bottom="30"/>
</Button.Margin>
</Button>
Opmerking
Er is ook een beperkt aantal objecten waarbij de typeconversie de enige openbare manier is om een eigenschap in te stellen op dat type zonder een subklasse te gebruiken, omdat het type zelf geen parameterloze constructor heeft. Een voorbeeld is Cursor.
Zie TypeConverters en XAML voor meer informatie over typeconversie.
Hoofdelementen en naamruimten
Een XAML-bestand mag slechts één hoofdelement hebben, om zowel een goed opgemaakt XML-bestand als een geldig XAML-bestand te zijn. Voor typische WPF-scenario's gebruikt u een hoofdelement met een prominente betekenis in het WPF-app-model (bijvoorbeeld Window voor Page een pagina, ResourceDictionary voor een externe woordenlijst of Application voor de app-definitie). In het volgende voorbeeld ziet u het hoofdelement van een typisch XAML-bestand voor een WPF-pagina, met het hoofdelement van Page.
<Page x:Class="index.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page1">
</Page>
Het hoofdelement bevat ook de kenmerken xmlns
en xmlns:x
. Deze kenmerken geven aan een XAML-processor aan welke XAML-naamruimten de typedefinities bevatten voor back-uptypen waarnaar de markeringen verwijzen als elementen. Het xmlns
kenmerk geeft specifiek de standaard XAML-naamruimte aan. In de standaard XAML-naamruimte kunnen objectelementen in de markering worden opgegeven zonder voorvoegsel. Voor de meeste WPF-app-scenario's en voor bijna alle voorbeelden in de WPF-secties van de SDK wordt de standaardnaamruimte XAML toegewezen aan de WPF-naamruimte http://schemas.microsoft.com/winfx/2006/xaml/presentation
. Het xmlns:x
-kenmerk geeft een extra XAML-naamruimte aan, die de XAML-taalnaamruimte http://schemas.microsoft.com/winfx/2006/xaml
toewijst.
Dit gebruik van xmlns
om een scope te definiëren voor het gebruik en de toewijzing van een naamruimte is consistent met de XML 1.0-specificatie. XAML-naamscopen verschillen alleen van XML-naamscopen omdat een XAML-naamscoop ook iets impliceert over hoe de elementen van de naamscoop worden ondersteund door typen als het gaat om typeresolutie en het parseren van de XAML.
De xmlns
kenmerken zijn alleen strikt noodzakelijk voor het hoofdelement van elk XAML-bestand.
xmlns
definities zijn van toepassing op alle onderliggende elementen van het hoofdelement (dit gedrag is opnieuw consistent met de XML 1.0-specificatie voor xmlns
.) xmlns
kenmerken zijn ook toegestaan op andere elementen onder de hoofdmap en zou van toepassing zijn op onderliggende elementen van het definiërende element. Frequente definitie of herdefinitie van XAML-naamruimten kan echter resulteren in een XAML-opmaakstijl die moeilijk te lezen is.
De WPF-implementatie van de XAML-processor bevat een infrastructuur die kennis heeft van de WPF-kernassembly's. De WPF-kernassemblies zijn bekend te bevatten de typen die de WPF-toewijzingen naar de standaard XAML-naamruimte ondersteunen. Dit wordt ingeschakeld via de configuratie die deel uitmaakt van uw projectbuildbestand en de WPF-build- en projectsystemen. Daarom is het declaratie van de standaard XAML-naamruimte als de standaardinstelling xmlns
alles wat nodig is om te verwijzen naar XAML-elementen die afkomstig zijn van WPF-assembly's.
Het x: voorvoegsel
In het vorige hoofdelementvoorbeeld is het voorvoegsel x:
gebruikt om de XAML-naamruimte http://schemas.microsoft.com/winfx/2006/xaml
toe te wijzen. Dit is de toegewezen XAML-naamruimte die XAML-taalconstructies ondersteunt. Dit x:
voorvoegsel wordt gebruikt om deze XAML-naamruimte te koppelen in de projectsjablonen, voorbeelden en documentatie binnen deze SDK. De XAML-naamruimte voor de XAML-taal bevat verschillende programmeerconstructies die u vaak in uw XAML gaat gebruiken. Hier volgt een overzicht van de meest voorkomende x:
voorvoegselprogrammeringsconstructies die u gaat gebruiken:
x:Key: Stelt een unieke sleutel in voor elke resource in een ResourceDictionary (of vergelijkbare woordenlijstconcepten in andere frameworks).
x:Key
is waarschijnlijk 90 procent van hetx:
gebruik dat u ziet in de markeringen van een typische WPF-app.x:Class: Hiermee geeft u de CLR-naamruimte en klassenaam op voor de klasse die code-behind biedt voor een XAML-pagina. U moet een dergelijke klasse hebben ter ondersteuning van het WPF-programmeermodel voor code-behind, en daarom ziet u
x:
bijna altijd gemapt, zelfs als er geen resources zijn.x:Name: Hiermee geeft u een runtime-objectnaam op voor het exemplaar dat in runtimecode bestaat nadat een objectelement is verwerkt. Over het algemeen gebruikt u vaak een door WPF gedefinieerde equivalente eigenschap voor x:Name. Dergelijke eigenschappen worden specifiek toegewezen aan een CLR-back-upeigenschap en zijn dus handiger voor het programmeren van apps, waarbij u vaak runtimecode gebruikt om de benoemde elementen te vinden van geïnitialiseerde XAML. De meest voorkomende eigenschap is FrameworkElement.Name. U kunt nog steeds x:Name gebruiken wanneer de equivalente eigenschap WPF-frameworkniveau Name niet wordt ondersteund in een bepaald type. Dit gebeurt in bepaalde animatiescenario's.
x:Static: Hiermee wordt een verwijzing ingeschakeld die een statische waarde retourneert die anders geen eigenschap is die compatibel is met XAML.
x:Type: Hiermee wordt een Type verwijzing samengesteld op basis van een typenaam. Dit wordt gebruikt om attributen op te geven die Type bevatten, zoals Style.TargetType, hoewel de eigenschap vaak een ingebouwde string-naar-Type conversie heeft op een zodanige manier dat het gebruik van de x:Type markeringsextensie optioneel is.
Er zijn extra programmeerconstructies in de x:
voorvoegsel-/XAML-naamruimte, die niet zo gebruikelijk zijn. Zie XAML-naamruimte (x:) Taalfuncties voor meer informatie.
Aangepaste voorvoegsels en aangepaste typen
Voor uw eigen aangepaste assembly's of voor assembly's buiten de WPF-kern van PresentationCore, PresentationFramework en WindowsBase kunt u de assembly opgeven als onderdeel van een aangepaste xmlns
toewijzing. U kunt vervolgens verwijzen naar typen uit die assembly in uw XAML, zolang dat type correct is geïmplementeerd ter ondersteuning van het XAML-gebruik dat u probeert te ondersteunen.
Hier volgt een eenvoudig voorbeeld van de werking van aangepaste voorvoegsels in XAML-markeringen. Het voorvoegsel custom
wordt gedefinieerd in de hoofdelementtag en toegewezen aan een specifieke assembly die is verpakt en beschikbaar is voor de app. Deze assembly bevat een type NumericUpDown
, dat wordt geïmplementeerd ter ondersteuning van algemeen XAML-gebruik en het gebruik van een klasseovername die het invoegen op dit specifieke punt in een WPF XAML-inhoudsmodel toestaat. Een exemplaar van dit NumericUpDown
besturingselement wordt gedeclareerd als een objectelement, waarbij gebruik wordt gemaakt van het voorvoegsel, zodat een XAML-parser weet in welke XAML-naamruimte het type zich bevindt en dus waar de backing-assembly met de typedefinitie te vinden is.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:custom="clr-namespace:NumericUpDownCustomControl;assembly=CustomLibrary"
>
<StackPanel Name="LayoutRoot">
<custom:NumericUpDown Name="numericCtrl1" Width="100" Height="60"/>
...
</StackPanel>
</Page>
Zie XAML en aangepaste klassen voor WPF voor meer informatie over aangepaste typen in XAML.
Voor meer informatie over de relatie tussen XML-naamruimten en codenaamruimten in assembly's, zie XAML-naamruimten en naamruimtetoewijzingen voor WPF XAML.
Gebeurtenissen en XAML-codeachter
De meeste WPF-apps bestaan uit zowel XAML-markeringen als code-behind. Binnen een project wordt de XAML geschreven als een .xaml
bestand en wordt een CLR-taal zoals Microsoft Visual Basic of C# gebruikt om een code-behind-bestand te schrijven. Wanneer een XAML-bestand is gecompileerd als onderdeel van de WPF-programmeer- en toepassingsmodellen, wordt de locatie van het XAML-codeachter-bestand voor een XAML-bestand geïdentificeerd door een naamruimte en klasse op te geven als het x:Class
kenmerk van het hoofdelement van de XAML.
In de voorbeelden tot nu toe hebt u verschillende knoppen gezien, maar deze knoppen hebben nog geen logisch gedrag eraan gekoppeld. Het primaire mechanisme op toepassingsniveau voor het toevoegen van een gedrag voor een objectelement is het gebruik van een bestaande gebeurtenis van de elementklasse en het schrijven van een specifieke handler voor die gebeurtenis die wordt aangeroepen wanneer deze gebeurtenis tijdens runtime wordt gegenereerd. De gebeurtenisnaam en de naam van de te gebruiken handler worden opgegeven in de markeringen, terwijl de code die uw handler implementeert, is gedefinieerd in de code-behind.
<Page x:Class="ExampleNamespace.ExamplePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<Button Click="Button_Click">Click me</Button>
</StackPanel>
</Page>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace ExampleNamespace;
public partial class ExamplePage : Page
{
public ExamplePage() =>
InitializeComponent();
private void Button_Click(object sender, RoutedEventArgs e)
{
var buttonControl = (Button)e.Source;
buttonControl.Foreground = Brushes.Red;
}
}
Class ExamplePage
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
Dim buttonControl = DirectCast(e.Source, Button)
buttonControl.Foreground = Brushes.Red
End Sub
End Class
U ziet dat het code-behind-bestand gebruikmaakt van de CLR-naamruimte ExampleNamespace
(de naamruimte is niet zichtbaar in Visual Basic) en declareert ExamplePage
als een gedeeltelijke klasse binnen die naamruimte. Dit komt overeen met de x:Class
kenmerkwaarde van ExampleNamespace
.
ExamplePage
die is opgegeven in de markering-root. De WPF-markeringscompilator maakt een gedeeltelijke klasse voor elk gecompileerd XAML-bestand door een klasse af te leiden van het type hoofdelement. Wanneer u code opgeeft die ook dezelfde gedeeltelijke klasse definieert, wordt de resulterende code gecombineerd binnen dezelfde naamruimte en klasse van de gecompileerde app.
Belangrijk
In Visual Basic wordt de hoofdnaamruimte geïmpliceerd voor zowel de XAML als de achterliggende code. Alleen geneste naamruimten zijn zichtbaar. In dit artikel wordt de XAML van het C#-project gedemonstreerde.
Zie Code-behind, Event Handler en Gedeeltelijke klassevereisten in WPF voor meer informatie over vereisten voor code-behind programmeren in WPF.
Als u geen afzonderlijk code-behind-bestand wilt maken, kunt u uw code ook inline plaatsen in een XAML-bestand. Inlinecode is echter een minder veelzijdige techniek die aanzienlijke beperkingen heeft. Zie Code-Behind en XAML in WPF voor meer informatie.
Gerouteerde gebeurtenissen
Een bepaalde gebeurtenisfunctie die fundamenteel is voor WPF, is een gerouteerde gebeurtenis. Met gerouteerde gebeurtenissen kan een element een gebeurtenis verwerken die door een ander element is gegenereerd, zolang de elementen zijn verbonden via een structuurrelatie. Wanneer u gebeurtenisafhandeling opgeeft met een XAML-kenmerk, kan naar de gerouteerde gebeurtenis worden geluisterd en deze kan worden afgehandeld op elk element, inclusief elementen die die specifieke gebeurtenis niet vermelden in de tabel met klasleden. Dit wordt bereikt door het kenmerk gebeurtenisnaam te kwalificeren met de naam van de eigenaar van de klasse. Het bovenliggende StackPanel
item in het lopende StackPanel
/ Button
voorbeeld kan bijvoorbeeld een handler registreren voor de gebeurtenis van de onderliggende knopelement Click door het kenmerk Button.Click
op te geven in het StackPanel
objectelement, met de naam van de handler als kenmerkwaarde. Zie Overzicht van gerouteerde gebeurtenissen voor meer informatie.
Benoemde elementen
Standaard beschikt het objectinstance dat wordt gecreëerd in een objectgrafiek bij het verwerken van een XAML-objectelement niet over een unieke identificatie of objectverwijzing. Als u daarentegen een constructor in code aanroept, gebruikt u bijna altijd het constructorresultaat om een variabele in te stellen op het samengestelde exemplaar, zodat u later in uw code naar het exemplaar kunt verwijzen. Om gestandaardiseerde toegang te bieden tot objecten die zijn gemaakt via een markeringsdefinitie, definieert XAML het kenmerk x:Name. U kunt de waarde van het x:Name
kenmerk instellen op elk objectelement. In de code-behind is de identifier die u kiest gelijk aan een instantievariabele die verwijst naar de geconstrueerde instantie. Benoemde elementen werken in alle opzichten alsof het objectexemplaren zijn (de naam verwijst naar dat exemplaar) en uw code-behind kan verwijzen naar de benoemde elementen om runtime-interacties binnen de app af te handelen. Deze verbinding tussen exemplaren en variabelen wordt gerealiseerd door de WPF XAML-markeringscompilator en betrek meer specifiek functies en patronen, zoals InitializeComponent die in dit artikel niet in detail worden besproken.
XAML-elementen op WPF-frameworkniveau nemen een Name eigenschap over, die gelijk is aan het XAML-gedefinieerde x:Name
kenmerk. Bepaalde andere klassen bieden ook equivalenten op eigenschapsniveau voor x:Name
, die meestal ook als een Name
eigenschap worden gedefinieerd. In het algemeen, als u geen eigenschap kunt vinden in het overzicht voor het gekozen element/type, gebruik Name
in plaats daarvan. De x:Name
waarden geven een id aan een XAML-element dat tijdens runtime kan worden gebruikt, hetzij door specifieke subsystemen of door hulpprogrammamethoden zoals FindName.
In het volgende voorbeeld wordt Name op een StackPanel-element gezet. Vervolgens verwijst een handler op een Button binnen die StackPanel naar de StackPanel via zijn instantieverwijzing buttonContainer
, zoals ingesteld door Name.
<StackPanel Name="buttonContainer">
<Button Click="RemoveThis_Click">Click to remove this button</Button>
</StackPanel>
private void RemoveThis_Click(object sender, RoutedEventArgs e)
{
var element = (FrameworkElement)e.Source;
if (buttonContainer.Children.Contains(element))
buttonContainer.Children.Remove(element);
}
Private Sub RemoveThis_Click(sender As Object, e As RoutedEventArgs)
Dim element = DirectCast(e.Source, FrameworkElement)
If buttonContainer.Children.Contains(element) Then
buttonContainer.Children.Remove(element)
End If
End Sub
Net als bij een variabele wordt de XAML-naam voor een exemplaar beheerd door een bereikconcept, zodat namen kunnen worden afgedwongen om uniek te zijn binnen een bepaald bereik dat voorspelbaar is. De primaire markering die een pagina definieert, geeft één unieke XAML-naamscoop aan, waarbij de XAML-naamscopegrens het hoofdelement van die pagina is. Andere opmaakbronnen kunnen echter tijdens runtime interactie hebben met een pagina, zoals stijlen of sjablonen binnen stijlen, en dergelijke markeringsbronnen hebben vaak hun eigen XAML-naamscopen die niet noodzakelijkerwijs verbinding maken met de XAML-naamscoop van de pagina. Zie x:Name
of Name voor meer informatie over en XAML-naamscopen.
Gekoppelde eigenschappen en gekoppelde gebeurtenissen
XAML geeft een taalfunctie op waarmee bepaalde eigenschappen of gebeurtenissen kunnen worden opgegeven voor een element, zelfs als de eigenschap of gebeurtenis niet bestaat in de definities van het type voor het element waarop het wordt ingesteld. De eigenschappenversie van deze functie wordt een gekoppelde eigenschap genoemd. De gebeurtenisversie wordt een gekoppelde gebeurtenis genoemd. Conceptueel gezien kunt u gekoppelde eigenschappen en gekoppelde gebeurtenissen beschouwen als globale leden die kunnen worden ingesteld op elk XAML-element/objectexemplaren. Het element of de klasse, of een grotere infrastructuur, moet echter ondersteuning bieden voor een eigenschappenopslag voor de gekoppelde waarden.
Gekoppelde eigenschappen in XAML worden doorgaans gebruikt via de syntaxis van het kenmerk. In de syntaxis van het kenmerk geeft u een gekoppelde eigenschap op in het formulier ownerType.propertyName
.
Oppervlakkig gezien lijkt dit op het gebruik van een eigenschapselement, maar in dit geval is de ownerType
door u opgegeven waarde altijd een ander type dan het objectelement waarin de gekoppelde eigenschap wordt ingesteld.
ownerType
is het type dat de toegangsmethoden biedt die vereist zijn voor een XAML-processor om de waarde van de gekoppelde eigenschap op te halen of in te stellen.
Het meest voorkomende scenario voor gekoppelde eigenschappen is om onderliggende elementen in staat te stellen een eigenschapswaarde te rapporteren aan het bovenliggende element.
In het volgende voorbeeld ziet u de DockPanel.Dock gekoppelde eigenschap. De DockPanel klasse definieert de toegangsrechten voor DockPanel.Dock en is eigenaar van de gekoppelde eigenschap. De DockPanel klasse bevat ook logica waarmee de onderliggende elementen worden herhaald en dat elk element specifiek wordt gecontroleerd op een setwaarde van DockPanel.Dock. Als er een waarde wordt gevonden, wordt die waarde tijdens de lay-out gebruikt om de elementen te plaatsen. Het gebruik van de DockPanel.Dock bijgevoegde eigenschap en deze positioneringsmogelijkheid is in feite het motiverende scenario voor de DockPanel klasse.
<DockPanel>
<Button DockPanel.Dock="Left" Width="100" Height="20">I am on the left</Button>
<Button DockPanel.Dock="Right" Width="100" Height="20">I am on the right</Button>
</DockPanel>
In WPF worden de meeste of alle gekoppelde eigenschappen ook geïmplementeerd als afhankelijkheidseigenschappen. Zie Overzicht van bijgevoegde eigenschappen voor meer informatie.
Gekoppelde gebeurtenissen maken gebruik van een vergelijkbare ownerType.eventName
vorm van kenmerksyntaxis. Net als bij de niet-gekoppelde gebeurtenissen geeft de kenmerkwaarde voor een gekoppelde gebeurtenis in XAML de naam op van de handlermethode die wordt aangeroepen wanneer de gebeurtenis wordt verwerkt op het element. Het gebruik van gekoppelde gebeurtenissen in WPF XAML komt minder vaak voor. Zie Overzicht van gekoppelde gebeurtenissen voor meer informatie.
Basistypen
Onderliggende WPF XAML en de bijbehorende XAML-naamruimte is een verzameling typen die overeenkomen met CLR-objecten en XAML-markupelementen. Niet alle klassen kunnen echter worden toegewezen aan elementen. Abstracte klassen, zoals ButtonBaseen bepaalde niet-abstracte basisklassen, worden gebruikt voor overname in het CLR-objectenmodel. Basisklassen, inclusief abstracte klassen, zijn nog steeds belangrijk voor de ontwikkeling van XAML, omdat elk van de concrete XAML-elementen leden overneemt van een bepaalde basisklasse in de hiërarchie. Deze leden bevatten vaak eigenschappen die kunnen worden ingesteld als kenmerken van het element of gebeurtenissen die kunnen worden verwerkt. FrameworkElement is de concrete basisgebruikersinterfaceklasse van WPF op het niveau van het WPF-framework. Bij het ontwerpen van de gebruikersinterface gebruikt u verschillende vorm-, paneel-, decorator- of besturingsklassen, die allemaal zijn afgeleid van FrameworkElement. Een gerelateerde basisklasse, FrameworkContentElement ondersteunt documentgeoriënteerde elementen die goed werken voor een presentatie met een stroomindeling, door gebruik te maken van API's die bewust de API's in FrameworkElement spiegelen. De combinatie van kenmerken op elementniveau en een CLR-objectmodel biedt u een set algemene eigenschappen die zijn ingesteld op de meeste concrete XAML-elementen, ongeacht het specifieke XAML-element en het onderliggende type.
Veiligheid
XAML is een opmaaktaal die rechtstreeks staat voor object instantiëring en uitvoering. Daarom hebben elementen die in XAML zijn gemaakt, dezelfde mogelijkheid om te communiceren met systeembronnen (netwerktoegang, io van bestandssysteem, bijvoorbeeld) als uw app-code. XAML heeft ook dezelfde toegang tot de systeembronnen als de hosting-app.
Code Access Security (CAS) in WPF
In tegenstelling tot .NET Framework biedt WPF voor .NET geen ondersteuning voor CAS. Zie Verschillen in codetoegangsbeveiliging voor meer informatie.
XAML laden vanuit code
XAML kan worden gebruikt om alle gebruikersinterfaces te definiëren, maar het is soms ook geschikt om slechts een deel van de gebruikersinterface in XAML te definiëren. Deze mogelijkheid kan worden gebruikt voor het volgende:
- Schakel gedeeltelijke aanpassing in.
- Lokale opslag van gebruikersinterfacegegevens.
- Een bedrijfsobject modelleren.
De sleutel voor deze scenario's is de XamlReader klasse en de Load bijbehorende methode. De invoer is een XAML-bestand en de uitvoer is een object dat alle runtimestructuur vertegenwoordigt van objecten die op basis van die markeringen zijn gemaakt. Vervolgens kunt u het object invoegen als een eigenschap van een ander object dat al in de app bestaat. Zolang de eigenschap zich in het inhoudsmodel bevindt en weergavemogelijkheden heeft waarmee de uitvoeringsengine wordt geïnformeerd dat er nieuwe inhoud aan de app is toegevoegd, kunt u de inhoud van een actieve app eenvoudig wijzigen door dynamisch te laden in XAML.
Zie ook
.NET Desktop feedback