Overzicht van XAML-resources
Een resource is een object dat opnieuw kan worden gebruikt op verschillende plaatsen in uw app. Voorbeelden van hulpmiddelen zijn borstels en stijlen. In dit overzicht wordt beschreven hoe u resources gebruikt in Extensible Application Markup Language (XAML). U kunt ook resources maken en openen met behulp van code.
Notitie
XAML-resources die in dit artikel worden beschreven, verschillen van app-resources die over het algemeen bestanden zijn die zijn toegevoegd aan een app, zoals inhoud, gegevens of ingesloten bestanden.
Resources gebruiken in XAML
In het volgende voorbeeld wordt een SolidColorBrush gedefinieerd als een resource op het hoofdelement van een pagina. Het voorbeeld verwijst vervolgens naar de resource en gebruikt deze om eigenschappen van verschillende onderliggende elementen in te stellen, waaronder een Ellipse, een TextBlocken een Button.
<Page Name="root"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Page.Resources>
<SolidColorBrush x:Key="MyBrush" Color="Gold"/>
<Style TargetType="Border" x:Key="PageBackground">
<Setter Property="Background" Value="Blue"/>
</Style>
<Style TargetType="TextBlock" x:Key="TitleText">
<Setter Property="Background" Value="Blue"/>
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="Foreground" Value="#4E87D4"/>
<Setter Property="FontFamily" Value="Trebuchet MS"/>
<Setter Property="Margin" Value="0,40,10,10"/>
</Style>
<Style TargetType="TextBlock" x:Key="Label">
<Setter Property="DockPanel.Dock" Value="Right"/>
<Setter Property="FontSize" Value="8"/>
<Setter Property="Foreground" Value="{StaticResource MyBrush}"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Margin" Value="0,3,10,0"/>
</Style>
</Page.Resources>
<StackPanel>
<Border Style="{StaticResource PageBackground}">
<DockPanel>
<TextBlock Style="{StaticResource TitleText}">Title</TextBlock>
<TextBlock Style="{StaticResource Label}">Label</TextBlock>
<TextBlock DockPanel.Dock="Top" HorizontalAlignment="Left" FontSize="36" Foreground="{StaticResource MyBrush}" Text="Text" Margin="20" />
<Button DockPanel.Dock="Top" HorizontalAlignment="Left" Height="30" Background="{StaticResource MyBrush}" Margin="40">Button</Button>
<Ellipse DockPanel.Dock="Top" HorizontalAlignment="Left" Width="100" Height="100" Fill="{StaticResource MyBrush}" Margin="40" />
</DockPanel>
</Border>
</StackPanel>
</Page>
Elk element op frameworkniveau (FrameworkElement of FrameworkContentElement) heeft een eigenschap Resources, een ResourceDictionary type dat gedefinieerde resources bevat. U kunt resources definiëren voor elk element, zoals een Button. Resources worden echter het vaakst gedefinieerd op het hoofdelement. Dit is Page in het voorbeeld.
Elke resource in een resourcewoordenboek moet een unieke sleutel hebben. Wanneer u resources in opmaak definieert, wijst u een unieke sleutel toe via de x:Key Directive. Normaal gesproken is de sleutel een tekenreeks; U kunt deze echter ook instellen op andere objecttypen met behulp van de juiste markeringsextensies. Niet-tekenreekssleutels voor resources worden gebruikt door bepaalde functiegebieden in WPF, met name voor stijlen, onderdeelbronnen en gegevensstijl.
U kunt een gedefinieerde resource gebruiken met de syntaxis van de extensie voor resourcemarkeringen waarmee de sleutelnaam van de resource wordt opgegeven. Gebruik de resource bijvoorbeeld als de waarde van een eigenschap op een ander element.
<Button Background="{StaticResource MyBrush}"/>
<Ellipse Fill="{StaticResource MyBrush}"/>
In het vorige voorbeeld, wanneer het XAML-laadprogramma de waarde {StaticResource MyBrush}
voor de eigenschap Background op Buttonverwerkt, controleert de logica voor het opzoeken van resources eerst de resourcewoordenlijst voor het Button-element. Als Button geen definitie heeft van de resourcesleutel MyBrush
(in dit voorbeeld is dat niet het geval; de resourceverzameling is leeg), controleert de zoekactie vervolgens het bovenliggende element van Button, dat Pageis. Als u een resource op het Page hoofdelement definieert, hebben alle elementen in de logische structuur van de Page er toegang toe. En u kunt dezelfde resource opnieuw gebruiken voor het instellen van de waarde van een eigenschap die hetzelfde type accepteert dat de resource vertegenwoordigt. In het vorige voorbeeld worden in dezelfde MyBrush
resource twee verschillende eigenschappen ingesteld: de Background van een Buttonen de Fill van een Rectangle.
Statische en dynamische bronnen
Er kan naar een resource worden verwezen als statisch of dynamisch. Verwijzingen worden gemaakt met behulp van de StaticResource Markup Extension of de DynamicResource Markup Extension. Een markeringsextensie is een XAML-functie waarmee u een objectverwijzing kunt opgeven door de kenmerkextensie de kenmerktekenreeks te laten verwerken en het object te retourneren aan een XAML-laadprogramma. Zie Markup Extensions en WPF XAMLvoor meer informatie over het gedrag van markeringsuitbreidingen.
Wanneer u een markeringsextensie gebruikt, geeft u doorgaans een of meer parameters op in tekenreeksformulieren die worden verwerkt door die specifieke markeringsextensie. De StaticResource Markup Extension verwerkt een sleutel door de waarde voor die sleutel in alle beschikbare resourcewoordenlijsten op te zoeken. De verwerking vindt plaats tijdens de belasting. Dit is wanneer het laadproces de eigenschapswaarde moet toewijzen. De DynamicResource Markup Extension verwerkt in plaats daarvan een sleutel door een expressie te maken en die expressie blijft niet geëvalueerd totdat de app wordt uitgevoerd, waarna de expressie wordt geëvalueerd en een waarde biedt.
Wanneer u naar een resource verwijst, kunnen de volgende overwegingen van invloed zijn op het gebruik van een statische resourcereferentie of een dynamische resourcereferentie:
Houd rekening met het volgende bij het bepalen van het algemene ontwerp van de wijze waarop u de resources voor uw app maakt (per pagina in de app, in losse XAML of in een assembly met alleen resources):
De functionaliteit van de app. Zijn het bijwerken van bronnen in real-time onderdeel van de vereisten voor uw app?
Het respectieve opzoekgedrag van dat bronreferentietype.
De specifieke eigenschap of het hulpbrontype en het eigen gedrag van deze typen.
Statische bronnen
Statische bronverwijzingen werken het beste voor de volgende omstandigheden:
Het ontwerp van uw app concentreert de meeste van zijn resources in bronnenwoordenlijsten op pagina- of toepassingsniveau. Statische resourceverwijzingen worden niet opnieuw geëvalueerd op basis van runtimegedrag, zoals het opnieuw laden van een pagina. Er kan dus een prestatievoordeel zijn om grote aantallen dynamische resourceverwijzingen te voorkomen wanneer ze niet nodig zijn op basis van uw resource- en app-ontwerp.
U stelt de waarde in van een eigenschap die zich niet op een DependencyObject of een Freezablebevindt.
U maakt een resourcewoordenlijst die wordt gecompileerd in een DLL en verpakt als onderdeel van de app of gedeeld tussen apps.
U maakt een thema voor een aangepast besturingselement en definieert resources die in de thema's worden gebruikt. In dit geval wilt u doorgaans niet dat het zoekgedrag voor dynamische bronverwijzingen wordt gebruikt; in plaats daarvan wilt u het gedrag van statische bronverwijzingen, zodat het zoekgedrag voorspelbaar en zelfstandig binnen het thema is. Met een dynamische resourceverwijzing wordt zelfs een verwijzing binnen een thema niet geëvalueerd totdat de runtime is uitgevoerd. en er is een kans dat wanneer het thema wordt toegepast, een lokaal element een sleutel opnieuw definieert waarnaar uw thema probeert te verwijzen, en het lokale element valt vóór het thema zelf in de zoekactie. Als dat gebeurt, gedraagt uw thema zich niet zoals verwacht.
U gebruikt resources om grote aantallen afhankelijkheidseigenschappen in te stellen. Afhankelijkheidseigenschappen hebben effectieve waardecache zoals ingeschakeld door het eigenschappensysteem, dus als u een waarde opgeeft voor een afhankelijkheidseigenschap die tijdens de laadtijd kan worden geëvalueerd, hoeft de eigenschap van de afhankelijkheid niet te controleren op een opnieuw geëvalueerde expressie en kan de laatste effectieve waarde retourneren. Deze techniek kan een prestatievoordeel zijn.
U wilt de onderliggende resource voor alle consumenten wijzigen of u wilt afzonderlijke schrijfbare exemplaren voor elke consument onderhouden met behulp van het x:Shared Attribute.
Gedrag bij het opzoeken van statische resources
Hieronder wordt het opzoekproces beschreven dat automatisch plaatsvindt wanneer naar een statische resource wordt verwezen door een eigenschap of element:
Het opzoekproces controleert op de aangevraagde sleutel binnen de resourcewoordenlijst die is gedefinieerd door het element dat de eigenschap instelt.
Het opzoekproces doorkruist vervolgens de logische structuur omhoog naar het bovenliggende element en de bijbehorende resourcewoordenlijst. Dit proces wordt voortgezet totdat het hoofdelement is bereikt.
App-resources worden gecontroleerd. App-resources zijn deze resources in de resourcewoordenlijst die is gedefinieerd door het Application-object voor uw WPF-app.
Statische resourceverwijzingen vanuit een resourcewoordenlijst moeten verwijzen naar een resource die al lexisch is gedefinieerd vóór de resourceverwijzing. Vooruitverwijzingen kunnen niet worden opgelost door een statische bronverwijzing. Daarom ontwerpt u de structuur van de resourceslijst zodanig dat resources worden gedefinieerd aan of bij het begin van elke respectieve resourceslijst.
Het opzoeken van statische resources kan worden uitgebreid naar thema's of in systeemresources, maar deze zoekopdracht wordt alleen ondersteund omdat het XAML-laadprogramma de aanvraag uitstelt. Het uitstel is nodig, zodat het runtimethema op het moment dat de pagina wordt geladen correct van toepassing is op de app. Statische resourceverwijzingen naar sleutels die alleen bestaan in thema's of als systeemresources worden niet aanbevolen, omdat dergelijke verwijzingen niet opnieuw worden geëvalueerd als het thema in realtime door de gebruiker wordt gewijzigd. Een dynamische resourcereferentie is betrouwbaarder wanneer u thema- of systeemresources aanvraagt. De uitzondering is wanneer een thema-element zelf een andere resource aanvraagt. Deze verwijzingen moeten statische bronverwijzingen zijn, om de eerder genoemde redenen.
Het uitzonderingsgedrag als een statische resourcereferentie niet wordt gevonden, varieert. Als de resource is uitgesteld, treedt de uitzondering op tijdens runtime. Als de resource niet is uitgesteld, ontstaat de uitzondering tijdens het laden.
Dynamische hulpbronnen
Dynamische middelen werken het beste wanneer:
De waarde van de resource, inclusief systeemresources of resources die anders door de gebruiker instelbaar zijn, is afhankelijk van voorwaarden die pas bekend zijn tot op het moment van uitvoering. U kunt bijvoorbeeld setterwaarden maken die verwijzen naar systeemeigenschappen die worden weergegeven door SystemColors, SystemFontsof SystemParameters. Deze waarden zijn echt dynamisch omdat ze uiteindelijk afkomstig zijn uit de runtime-omgeving van de gebruiker en het besturingssysteem. Mogelijk hebt u ook thema's op toepassingsniveau die kunnen worden gewijzigd, waarbij ook de toegang tot resources op paginaniveau de wijziging moet vastleggen.
U maakt of verwijst naar themastijlen voor een aangepast bedieningselement.
U bent van plan om de inhoud van een ResourceDictionary tijdens de levensduur van een app aan te passen.
U hebt een gecompliceerde resourcestructuur met onderlinge afhankelijkheden, waarbij mogelijk een doorstuurreferentie vereist is. Statische resourceverwijzingen bieden geen ondersteuning voor vooruitverwijzingen, maar dynamische resourceverwijzingen ondersteunen ze wel omdat de resource niet hoeft te worden geëvalueerd tot tijdens runtime, en doorstuurverwijzingen daarom geen relevant concept zijn.
U verwijst naar een resource die groot is vanuit het perspectief van een compileer- of werkset en de resource wordt mogelijk niet onmiddellijk gebruikt wanneer de pagina wordt geladen. Statische resourceverwijzingen worden altijd geladen vanuit XAML wanneer de pagina wordt geladen. Een dynamische resourcereferentie wordt echter pas geladen als deze wordt gebruikt.
U maakt een stijl waarbij setterwaarden kunnen afkomstig zijn van andere waarden die worden beïnvloed door thema's of andere gebruikersinstellingen.
U past resources toe op elementen die mogelijk tijdens de levensduur van de app opnieuw worden gebruikt in de logische structuur. Als u het bovenliggende element wijzigt, wordt mogelijk ook het bereik voor het opzoeken van resources gewijzigd. Wilt u dat de resource voor een opnieuw toegewezen element opnieuw wordt geëvalueerd op basis van het nieuwe bereik, dan moet u altijd een dynamische resourceverwijzing gebruiken.
Dynamisch gedrag voor het opzoeken van resources
Het opzoekgedrag van resources voor een dynamische resourcereferentie parallelleert het opzoekgedrag in uw code als u FindResource of SetResourceReferenceaanroept:
De zoekopdracht controleert op de opgevraagde sleutel in de bronnenwoordenlijst die is gedefinieerd door het element dat de eigenschap instelt.
Als het element een eigenschap Style definieert, wordt de Resources-woordenlijst van de System.Windows.FrameworkElement.Style van het element gecontroleerd.
Als het element een eigenschap Template definieert, wordt de System.Windows.FrameworkTemplate.Resources woordenlijst van het element gecontroleerd.
De opzoekactie gaat naar boven door de logische structuur naar het bovenliggende element en de bijbehorende bronnenlijst. Dit proces wordt voortgezet totdat het hoofdelement is bereikt.
App-resources worden gecontroleerd. App-resources zijn die resources in de resourcewoordenlijst die zijn gedefinieerd door het Application-object voor uw WPF-app.
De themaresourcewoordenlijst wordt gecontroleerd op het huidige actieve thema. Als het thema tijdens runtime wordt gewijzigd, wordt de waarde opnieuw geëvalueerd.
Systeembronnen worden gecontroleerd.
Uitzonderingsgedrag (indien aanwezig) varieert:
Als een resource is aangevraagd door een FindResource-aanroep en niet is gevonden, wordt er een uitzondering gegenereerd.
Als een resource is aangevraagd door een TryFindResource-aanroep en niet is gevonden, wordt er geen uitzondering gegenereerd en wordt de geretourneerde waarde
null
. Als de eigenschap die wordt ingesteld, geennull
accepteert, is het nog steeds mogelijk dat er een diepere uitzondering wordt gegenereerd, afhankelijk van de afzonderlijke eigenschap die wordt ingesteld.Als een resource is aangevraagd door een dynamische resourcereferentie in XAML en niet is gevonden, is het gedrag afhankelijk van het algemene eigenschappensysteem. Het algemene gedrag is alsof er geen eigenschapsinstellingsbewerking heeft plaatsgevonden op het niveau waarop de resource bestaat. Als u bijvoorbeeld probeert de achtergrond in te stellen op een afzonderlijk knopelement met behulp van een resource die niet kan worden geëvalueerd, wordt er geen waarde ingesteld, maar kan de effectieve waarde nog steeds afkomstig zijn van andere deelnemers aan het eigenschappensysteem en de waardepreferentie. De achtergrondwaarde kan bijvoorbeeld nog steeds afkomstig zijn van een lokaal gedefinieerde knopstijl of van de themastijl. Voor eigenschappen die niet zijn gedefinieerd door themastijlen, kan de effectieve waarde na een mislukte resource-evaluatie afkomstig zijn van de standaardwaarde in de metagegevens van de eigenschap.
Beperkingen
Dynamische resourceverwijzingen hebben enkele belangrijke beperkingen. Ten minste een van de volgende voorwaarden moet waar zijn:
De eigenschap die wordt ingesteld, moet een eigenschap zijn op een FrameworkElement of FrameworkContentElement. Dit kenmerk moet worden ondersteund door een DependencyProperty.
De verwijzing is voor een waarde binnen een
StyleSetter
.De eigenschap die wordt ingesteld, moet een eigenschap zijn op een Freezable die wordt opgegeven als een waarde van een eigenschap FrameworkElement of FrameworkContentElement, of een Setter waarde.
Omdat de eigenschap die wordt ingesteld, een DependencyProperty of Freezable eigenschap moet zijn, kunnen de meeste eigenschapswijzigingen worden doorgegeven aan de gebruikersinterface omdat een eigenschapswijziging (de gewijzigde dynamische resourcewaarde) wordt bevestigd door het eigenschappensysteem. De meeste besturingselementen bevatten logica waarmee een andere indeling van een besturingselement wordt afgedwongen als een DependencyProperty wordt gewijzigd en die eigenschap van invloed kan zijn op de indeling. Niet alle eigenschappen die een DynamicResource Markup-extensie als hun waarde hebben, zijn gegarandeerd in staat om realtime-updates te geven in de gebruikersinterface. Deze functionaliteit kan nog steeds variëren, afhankelijk van de eigenschap en afhankelijk van het type dat eigenaar is van de eigenschap, of zelfs de logische structuur van uw app.
Stijlen, DataTemplates en impliciete sleutels
Hoewel alle items in een ResourceDictionary een sleutel moeten hebben, betekent dit niet dat alle resources een expliciete x:Key
moeten hebben. Verschillende objecttypen ondersteunen een impliciete sleutel wanneer deze is gedefinieerd als een resource, waarbij de sleutelwaarde is gekoppeld aan de waarde van een andere eigenschap. Dit type sleutel wordt een impliciete sleutel genoemd, terwijl een x:Key
kenmerk een expliciete sleutel is. U kunt impliciete sleutels overschrijven door een expliciete sleutel op te geven.
Een belangrijk scenario voor resources is wanneer je een Styledefinieert. In feite wordt een Style bijna altijd gedefinieerd als een vermelding in een resourcewoordenlijst, omdat stijlen inherent zijn bedoeld voor hergebruik. Zie Styling and Templatingvoor meer informatie over stijlen.
Stijlen voor bedieningselementen kunnen worden gemaakt en aangeroepen met een impliciete sleutel. De themastijlen waarmee het standaard uiterlijk van een besturingselement wordt gedefinieerd, zijn afhankelijk van deze impliciete sleutel. Vanuit het oogpunt van het aanvragen is de impliciete sleutel de Type van het besturingselement zelf. Wat betreft het definiëren van de resources, is de impliciete sleutel de TargetType van de stijl. Als u daarom thema's maakt voor aangepaste besturingselementen of stijlen maakt die met bestaande themastijlen werken, hoeft u geen x:Sleutelrichtlijn op te geven voor die Style. En als u de themastijlen wilt gebruiken, hoeft u helemaal geen stijl op te geven. De volgende stijldefinitie werkt bijvoorbeeld, ook al lijkt de Style resource geen sleutel te hebben:
<Style TargetType="Button">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="AliceBlue"/>
<GradientStop Offset="1.0" Color="Salmon"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="18"/>
</Style>
Die stijl heeft echt een sleutel: de impliciete sleutel typeof(System.Windows.Controls.Button)
. In markeringen kunt u een TargetType rechtstreeks opgeven als de typenaam (of u kunt eventueel {x:Type...} gebruiken om een Typete retourneren.
Via de standaardthemastijlmechanismen die door WPF worden gebruikt, wordt die stijl toegepast als runtimestijl van een Button op de pagina, ook al probeert de Button zelf niet de Style eigenschap of een specifieke resourcereferentie naar de stijl op te geven. De stijl die op de pagina is gedefinieerd, vindt u eerder in de opzoekvolgorde dan de themawoordenlijststijl, met dezelfde sleutel als de themawoordenlijststijl. U kunt <Button>Hello</Button>
overal op de pagina opgeven en de stijl die u hebt gedefinieerd met TargetType van Button
zou op die knop van toepassing zijn. Als u wilt, kunt u de stijl nog steeds expliciet versleutelen met dezelfde typewaarde als TargetType voor duidelijkheid in uw markeringen, maar dat is optioneel.
Impliciete sleutels voor stijlen zijn niet van toepassing op een controle wanneer OverridesDefaultStyletrue
is. (Houd er ook rekening mee dat OverridesDefaultStyle mogelijk wordt ingesteld als onderdeel van het inherente gedrag voor de besturingsklasse, in plaats van expliciet op een exemplaar van het besturingselement.) Ook, om impliciete sleutels voor afgeleide klassescenario's te ondersteunen, moet het besturingselement DefaultStyleKey overschrijven (alle bestaande besturingselementen die als onderdeel van WPF worden geleverd, bevatten deze overschrijving). Zie Richtlijnen voor het ontwerpen van stijlbare bedieningselementenvoor meer informatie over stijlen, thema's en het ontwerp van bedieningselementen.
DataTemplate heeft ook een impliciete sleutel. De impliciete sleutel voor een DataTemplate is de eigenschapswaarde DataType. DataType kan ook worden opgegeven als de naam van het type in plaats van expliciet {x:Type...}. Voor meer informatie, zie Overzicht van gegevenssjablonering.
Zie ook
.NET Desktop feedback