Overzicht van XAML-resources (WPF .NET)
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. Dit zijn meestal bestanden 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.
<Window x:Class="resources.ResExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ResExample" Height="400" Width="300">
<Window.Resources>
<SolidColorBrush x:Key="MyBrush" Color="#05E0E9"/>
<Style TargetType="Border">
<Setter Property="Background" Value="#4E1A3D" />
<Setter Property="BorderThickness" Value="5" />
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="#4E1A3D"/>
<GradientStop Offset="1.0" Color="Salmon"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TextBlock" x:Key="TitleText">
<Setter Property="FontSize" Value="18"/>
<Setter Property="Foreground" Value="#4E87D4"/>
<Setter Property="FontFamily" Value="Trebuchet MS"/>
<Setter Property="Margin" Value="0,10,10,10"/>
</Style>
<Style TargetType="TextBlock" x:Key="Label">
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="FontSize" Value="13"/>
<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>
</Window.Resources>
<Border>
<StackPanel>
<TextBlock Style="{StaticResource TitleText}">Title</TextBlock>
<TextBlock Style="{StaticResource Label}">Label</TextBlock>
<TextBlock HorizontalAlignment="Right" FontSize="36" Foreground="{StaticResource MyBrush}" Text="Text" Margin="20" />
<Button HorizontalAlignment="Left" Height="30" Background="{StaticResource MyBrush}" Margin="40">Button</Button>
<Ellipse HorizontalAlignment="Center" Width="100" Height="100" Fill="{StaticResource MyBrush}" Margin="10" />
</StackPanel>
</Border>
</Window>
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 Window in het voorbeeld.
Elke resource in een bronnenwoordenboek moet een unieke sleutel hebben. Wanneer u resources in markup 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 resource-sleutel MyBrush
(in dat voorbeeld is dat niet het geval; de resourceverzameling is leeg), wordt er vervolgens gekeken naar het bovenliggende element van Button
. Als de resource niet is gedefinieerd op het bovenliggende item, blijft het de logische boom van het object naar boven controleren totdat het is gevonden.
Als u resources op het hoofdelement definieert, hebben alle elementen in de logische structuur, zoals de Window of 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: Button.Background en Ellipse.Fill.
Statische en dynamische middelen
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 om een waarde op te geven.
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. Is het bijwerken van bronnen in real-time een onderdeel van de vereisten voor uw app?
Het respectieve opzoekgedrag van dat bronreferentietype.
De specifieke eigenschap en het resourcetype, en het inherente 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 resourcewoordenboeken 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 is gecompileerd in een DLL die wordt 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 resources wordt gebruikt. Gebruik in plaats daarvan het gedrag van statische resourceverwijzingen zodat de zoekactie voorspelbaar en zelfstandig is voor het thema. 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 van 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 de aangevraagde sleutel in de bronnenwoordenlijst die is gedefinieerd door het element dat de eigenschap instelt.
Het opzoekproces doorloopt vervolgens de logische structuur naar boven tot het bovenliggende element en het bronnenwoordenboek. Dit proces wordt voortgezet totdat het hoofdelement is bereikt.
App-resources worden gecontroleerd. Applicatiebronnen zijn de resources in het woordenboek van de resources dat 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. Voorwaartse verwijzingen kunnen niet worden opgelost door een statische resourceverwijzing. Daarom ontwerpt u de structuur van de bronnenlijst zodanig dat resources aan het begin of dichtbij het begin van elke bronnenlijst worden gedefinieerd.
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 correct van toepassing is op de applicatie op het moment dat de pagina wordt geladen. 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 de gebruiker het thema in realtime wijzigt. 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 wordt uitgesteld, treedt de uitzondering op tijdens het laden.
Dynamische middelen
Dynamische resources werken het beste wanneer:
De waarde van de resource, inclusief systeemresources of resources die door de gebruiker kunnen worden ingesteld, is afhankelijk van omstandigheden die pas bekend zijn tot runtime. 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 stijlen van een thema voor een aangepast controle-element.
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 ondersteunen geen vooruit verwijzingen, maar dynamische resourceverwijzingen ondersteunen ze wel omdat de resource pas tijdens runtime hoeft te worden geëvalueerd en vooruit verwijzingen 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 ouder element wijzigt, wordt mogelijk ook het bereik voor het opzoeken van resources gewijzigd. Als u wilt dat de resource voor een herbepaald element op basis van het nieuwe bereik herschikt wordt, gebruikt u altijd een dynamische resourceverwijzing.
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 zoekactie controleert de aangevraagde sleutel binnen de bronnenwoordenlijst die is gedefinieerd door het element dat de eigenschap instelt.
Als het element een eigenschap Style definieert, wordt de System.Windows.FrameworkElement.Style van het element gecontroleerd op de Resources-woordenlijst.
Als het element een eigenschap Template definieert, wordt de System.Windows.FrameworkTemplate.Resources woordenlijst van het element gecontroleerd.
De opzoekactie doorloopt de logische boom naar boven, naar het bovenliggende element en zijn bronnenlijst. Dit proces wordt voortgezet totdat het hoofdelement is bereikt.
App-resources worden gecontroleerd. App-bronnen zijn de bronnen in het resourcedictionary die worden gedefinieerd door het Application-object voor uw WPF-app.
Het themabronwoordenboek wordt gecontroleerd op het 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 individueel knopelement met behulp van een resource die niet kan worden geëvalueerd, dan resulteert dit in geen waarde-instelling, maar kan de effectieve waarde nog steeds afkomstig zijn van andere deelnemers aan het eigenschappensysteem en de waardenvoorrang. 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 van een FrameworkElement of FrameworkContentElement. Dit kenmerk moet worden ondersteund door een DependencyProperty.
De verwijzing betreft een waarde binnen een
StyleSetter
.De eigenschap die wordt ingesteld, moet een eigenschap zijn op een Freezable, die als waarde van een eigenschap FrameworkElement of FrameworkContentElement wordt verstrekt, 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 Extension als waarde hebben, zullen echter gegarandeerd realtime-updates in de gebruikersinterface bieden. 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 en een x:Key
kenmerk is een expliciete sleutel. U kunt impliciete sleutels overschrijven door een expliciete sleutel op te geven.
Een belangrijk scenario voor resources is wanneer u een Styledefinieert. In feite wordt een Style bijna altijd gedefinieerd als een vermelding in een resourcewoordenlijst, omdat stijlen inherent zijn bedoeld voor hergebruik. Zie stijlen en sjablonen (WPF .NET)voor meer informatie over stijlen.
Stijlen voor besturingselementen kunnen zowel worden gecreëerd als worden 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. Vanuit het oogpunt van het definiëren van de resources is de impliciete sleutel de TargetType van de stijl. Als u thema's voor aangepaste bedieningselementen maakt of stijlen maakt die met bestaande themastijlen werken, hoeft u geen x:Key Directive- voor die Styleop te geven. 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" Value="#4E1A3D" />
<Setter Property="Foreground" Value="White" />
<Setter Property="BorderThickness" Value="5" />
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="#4E1A3D"/>
<GradientStop Offset="1.0" Color="Salmon"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
Die stijl heeft echt een sleutel: de impliciete sleutel: het System.Windows.Controls.Button
type. In markeringen kunt u een TargetType rechtstreeks opgeven als de typenaam (of u kunt eventueel {x:Type...} gebruiken om een Typete retourneren.
Door middel van de standaardthemamechanismen die door WPF worden gebruikt, wordt die stijl toegepast als de runtimestijl van een Button op de pagina, ook al doet de Button zelf geen poging om de Style-eigenschap of een specifieke resourcereferentie voor de stijl te specificeren. 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 gelden niet op een controle als OverridesDefaultStyle is true
. (Houd er ook rekening mee dat OverridesDefaultStyle mogelijk wordt ingesteld als onderdeel van natuurlijk gedrag voor de besturingsklasse, in plaats van expliciet op een instantie van het besturingselement.) Om impliciete sleutels voor afgeleide klassescenario's te ondersteunen, moet het besturingselement ook DefaultStyleKey overschrijven (alle bestaande besturingselementen die als onderdeel van WPF worden geleverd, omvatten deze overschrijving). Voor meer informatie over stijlen, thema's en het ontwerp van stijlbare besturingselementen, zie Richtlijnen voor het ontwerpen van stijlbare besturingselementen.
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...}. Zie Overzicht van gegevens templatingvoor meer informatie.
Zie ook
- Hulpmiddelen in code
- Samengevoegde resourcewoordenboeken
- Een WPF-resource definiëren en ernaar verwijzen
- Systeembronnen gebruiken
- Toepassingsbronnen gebruiken
- x:Type markup-uitbreiding
- ResourceDictionary
- toepassingsbronnen
- een resource definiëren en ernaar verwijzen
- Overzicht van toepassingsbeheer
- StaticResource-markup-extensie
- DynamicResource-markupextensie
.NET Desktop feedback