Een consistente gebruikersinterface maken met behulp van stijlen
In .NET Multi-Platform App UI (MAUI) zijn resources ideaal voor het vermijden van in code vastgelegde, dubbele waarden in uw XAML-opmaak (Extensible Application Markup Language), maar ze kunnen lastig zijn om toe te passen. U wijst elke eigenschapswaarde afzonderlijk toe, wat kan leiden tot onbelangrijke en uitgebreide XAML. In deze les ziet u hoe u meerdere instellingen in een stijl kunt groeperen, waardoor u uw code kunt opslonken en deze beter kunt onderhouden.
Hoe resources uw XAML overzichtelijker kunnen maken
Een resource biedt een waarde voor één eigenschap. Het gebruik van veel resources kan echter leiden tot uitgebreide XAML. Stel dat u een aangepast uiterlijk wilt voor uw knoppen. U maakt eerst resources voor de waarden die u nodig hebt. Vervolgens past u elke resource toe op al uw knoppen. De volgende code laat zien hoe de XAML-markering kan zoeken naar twee knoppen.
<Button
Text = "OK"
BackgroundColor = "{StaticResource highlightColor}"
BorderColor = "{StaticResource borderColor}"
BorderWidth = "{StaticResource borderWidth}"
TextColor = "{StaticResource textColor}" />
<Button
Text = "Cancel"
BackgroundColor = "{StaticResource highlightColor}"
BorderColor = "{StaticResource borderColor}"
BorderWidth = "{StaticResource borderWidth}"
TextColor = "{StaticResource textColor}" />
U ziet hoe dezelfde vijf eigenschappen op elk van de knoppen zijn ingesteld. Als u resources gebruikt, hebt u geen herhaalde, in code vastgelegde waarden meer nodig. Dit type XAML-markering wordt echter snel moeilijk te lezen. Als u voor elk besturingselement een groot aantal eigenschappen instelt, kunt u per ongeluk een van deze eigenschappen weglaten, wat leidt tot inconsistenties in het uiterlijk van de besturingselementen. De oplossing is het maken van een stijl die alle vier de eigenschappen tegelijk toewijst.
Wat is een setter?
Setters zijn de belangrijkste onderdelen die u gebruikt om stijlen te maken.
Een setter is een container voor een eigenschap/waardepaar. U kunt een setter beschouwen als een toewijzingsinstructie. U geeft op welke eigenschap moet worden toegewezen en welke waarde moet worden toegepast. Meestal maakt u Setter-objecten in uw XAML-markering. In het volgende voorbeeld wordt een Setter-object gemaakt voor de eigenschap TextColor .
<Setter Property="TextColor" Value="White" />
U kunt een resource gebruiken voor de waarde in een setter, zoals wordt weergegeven in de volgende code. Deze techniek is handig als u dezelfde waarde in meerdere setters wilt gebruiken.
<Setter Property="TextColor" Value="{StaticResource textColor}" />
Notitie
De eigenschapswaarde die u in een setter opgeeft, moet worden geïmplementeerd als een bindbare eigenschap. Alle eigenschappen op besturingselementen in .NET MAUI die eindigen op de eigenschap achtervoegsel zijn bindbare eigenschappen. Als u een eigenschap zoals TextColor in een setter wilt gebruiken, controleert u of er een bijbehorende bindbare eigenschap is met de naam TextColorProperty voor dat besturingselement . In de praktijk worden bijna alle eigenschappen die u in uw setters wilt gebruiken op deze manier geïmplementeerd.
Wat is een stijl?
Een stijl is een verzameling setters die zijn gericht op een specifiek type besturingselement. .NET MAUI vereist een doeltype, zodat deze ervoor kan zorgen dat de eigenschappen in uw setters bestaan op dat type.
De volgende code toont een stijl die de vier waarden uit het vorige voorbeeld combineert. U ziet dat TargetType is ingesteld op Knop en alle eigenschappen in de setters lid zijn van de knopklasse . U kunt deze stijl niet gebruiken voor een label, omdat de labelklasse de eigenschap BorderColor of BorderWidth niet bevat.
<Style TargetType="Button">
<Setter Property="BackgroundColor" Value="#2A84D3" />
<Setter Property="BorderColor" Value="#1C5F9B" />
<Setter Property="BorderWidth" Value="3" />
<Setter Property="TextColor" Value="White" />
</Style>
Een stijl definiëren
Doorgaans definieert u stijlen als resources in een ResourceDictionary-object . Met een resourcewoordenlijst kunt u de stijl eenvoudig gebruiken voor meerdere besturingselementen op dezelfde pagina of zelfs voor de hele toepassing. De volgende code laat zien hoe u een stijl definieert als een resource in een woordenlijst. U ziet dat de stijl een naam krijgt met behulp van de eigenschap x:Key . Als u een stijl een naam geeft, kunt u ernaar verwijzen vanuit uw XAML-pagina's.
<ContentPage.Resources>
<Style x:Key="MyButtonStyle" TargetType="Button">
...
</Style>
</ContentPage.Resources>
Een stijl toepassen
U koppelt een stijl aan een besturingselement door de naam toe te wijzen aan de eigenschap Stijl . De toewijzing zorgt ervoor dat elk van de Setter-objecten in de stijl wordt toegepast op het doelbeheer. De volgende code laat zien hoe u een knopstijl toepast op twee knoppen.
<Button Text="OK" Style="{StaticResource MyButtonStyle}" />
<Button Text="Cancel" Style="{StaticResource MyButtonStyle}" />
In het vorige voorbeeld hebt u de markeringsextensie StaticResource gebruikt om de stijl aan de besturingselementen te koppelen. Deze techniek is handig als u de stijl niet nodig hebt om tijdens runtime te wijzigen. Maar wat als u iets als dynamische thema's wilt implementeren, waar de gebruikersinterface moet veranderen? In dit geval kunt u de mark-upextensie DynamicResource gebruiken om de stijl te laden.
<Button Text="Cancel" Style="{DynamicResource MyButtonStyle}" />
DynamicResource luistert naar vervanging van de eigenschap x:Key in de resourcewoordenlijst. Als u code schrijft waarmee een nieuwe stijl wordt geladen in ResourceDictionary met dezelfde x:Key-waarde , wordt de nieuwe stijl automatisch toegepast op uw gebruikersinterface.
Een impliciete stijl gebruiken voor meerdere besturingselementen
Stel dat uw gebruikersinterface 50 knoppen heeft en u dezelfde stijl wilt toepassen op alle knoppen. Met wat we tot nu toe weten, moet u handmatig toewijzen aan de eigenschap Stijl op elke knop. Het is niet zo moeilijk om te doen, maar het is nog steeds vervelend.
Een impliciete stijl is een stijl die u aan een resourcewoordenlijst toevoegt zonder deze een x:Key-id te geven. Impliciete stijlen worden automatisch toegepast op alle besturingselementen van het opgegeven TargetType-object .
De volgende code toont het vorige voorbeeld dat is gedeclareerd als een impliciete stijl. Deze stijl wordt toegepast op elke knop op de pagina.
<ContentPage.Resources>
<Style TargetType="Button">
<Setter Property="BackgroundColor" Value="Blue" />
<Setter Property="BorderColor" Value="Navy" />
...
</Style>
</ContentPage.Resources>
Belangrijk
Voor het vergelijken van impliciete stijlen voor besturingselementen is een exacte overeenkomst met het opgegeven TargetType vereist. Besturingselementen die overnemen van het doeltype, ontvangen de stijlen niet. Als u van invloed wilt zijn op overgenomen besturingselementen, kunt u het kenmerk Style.ApplyToDerivedTypes instellen op True wanneer u de stijl definieert. Als u bijvoorbeeld een stijl wilt toepassen op het knoptype en dit van invloed hebt op een van uw knoppen die overnemen van knop (zoals een ImageButton, RadioButton of een aangepast type dat u maakt), kunt u een dergelijke stijl gebruiken.
<ContentPage.Resources>
<Style TargetType="Button"
ApplyToDerivedTypes="True">
<Setter Property="BackgroundColor" Value="Black" />
</Style>
</ContentPage.Resources>
Een stijl overschrijven
U kunt een stijl beschouwen als het instellen van een set standaardwaarden voor besturingselementen. Een bestaande stijl is mogelijk dicht bij uw vereisten, maar bevat een of twee setters die u niet wilt. In dat geval kunt u de stijl toepassen en vervolgens de waarde overschrijven door eigenschappen rechtstreeks in te stellen. De expliciete instelling wordt toegepast na de stijl, zodat de waarde uit de stijl wordt overschreven.
Stel dat u de volgende stijl wilt gebruiken voor verschillende knoppen op uw pagina.
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="BackgroundColor" Value="Blue" />
<Setter Property="BorderRadius" Value="10" />
<Setter Property="BorderWidth" Value="3" />
</Style>
Deze stijl werkt voor al uw knoppen behalve Annuleren, waarvoor een rode achtergrond nodig is. U kunt dezelfde stijl gebruiken voor de knop Annuleren, zolang u ook de eigenschap BackgroundColor rechtstreeks instelt. De volgende code laat zien hoe u de kleurinstelling overschrijft.
<Button
Text="Cancel"
Style="{StaticResource MyButtonStyle}"
BackgroundColor="Red"
... />
Doel van een bovenliggend type
Stel dat u een aangepaste achtergrondkleur wilt voor uw knoppen en labels. U kunt afzonderlijke stijlen maken voor elk type of u kunt één stijl maken met TargetType ingesteld op VisualElement. Deze techniek werkt omdat VisualElement een basisklasse is voor zowel Knop als Label.
De volgende code toont een stijl die is gericht op een basisklasse die wordt toegepast op twee verschillende afgeleide typen.
<Style x:Key="MyVisualElementStyle" TargetType="VisualElement">
<Setter Property="BackgroundColor" Value="#2A84D3" />
</Style>
...
<Button Style="{StaticResource MyVisualElementStyle}" ... />
<Label Style="{StaticResource MyVisualElementStyle}" ... />
In dit voorbeeld wordt de stijl geïdentificeerd met behulp van x:Key en de besturingselementen worden deze expliciet toegepast. Een impliciete stijl werkt hier niet omdat TargetType voor een impliciete stijl een exacte overeenkomst moet zijn met het type besturingselement.
BasedOn gebruiken om over te nemen van een stijl
Stel dat u een samenhangende look wilt maken voor uw gebruikersinterface. U besluit dat alle besturingselementen een consistente achtergrondkleur moeten gebruiken. De achtergrondkleurinstelling wordt waarschijnlijk weergegeven in meer dan een van uw stijlen. De volgende code toont twee stijlen met een herhaalde setter.
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="BackgroundColor" Value="Blue" />
<Setter Property="BorderColor" Value="Navy" />
<Setter Property="BorderWidth" Value="5" />
</Style>
<Style x:Key="MyEntryStyle" TargetType="Entry">
<Setter Property="BackgroundColor" Value="Blue" />
<Setter Property="TextColor" Value="White" />
</Style>
U kunt stijlovername gebruiken om de dubbele setter in een basisstijl te factoren. Als u een afgeleide stijl wilt maken, stelt u de eigenschap BasedOn in om te verwijzen naar de basisstijl. De nieuwe stijl neemt alle setters over van de basisstijl. De afgeleide stijl kan ook nieuwe setters toevoegen of een overgenomen setter vervangen door een setter die een andere waarde bevat.
De volgende code toont de stijlen uit het vorige voorbeeld die in een hiërarchie zijn geherstructureerd. De algemene setter wordt alleen weergegeven in de basisstijl in plaats van herhaald te worden. U ziet dat u de markeringsextensie StaticResource gebruikt om de basisstijl op te zoeken. In deze situatie kunt u DynamicResource niet gebruiken.
<Style x:Key="MyVisualElementStyle" TargetType="VisualElement">
<Setter Property="BackgroundColor" Value="Blue" />
</Style>
<Style x:Key="MyButtonStyle" TargetType="Button" BasedOn="{StaticResource MyVisualElementStyle}">
<Setter Property="BorderColor" Value="Navy" />
<Setter Property="BorderWidth" Value="5" />
</Style>
<Style x:Key="MyEntryStyle" TargetType="Entry" BasedOn="{StaticResource MyVisualElementStyle}">
<Setter Property="TextColor" Value="White" />
</Style>
De TargetType-waarde van de basis- en afgeleide stijlen moet compatibel zijn. Als u wilt dat de stijlen compatibel zijn, moeten ze dezelfde eigenschap TargetType hebben of het TargetType van de afgeleide stijl een afstamming is van het TargetType van de basisstijl.