Vytvoření konzistentního uživatelského rozhraní pomocí stylů
- 8 min
V uživatelském rozhraní aplikace .NET s více platformami (MAUI) jsou prostředky skvělé pro zabránění pevně zakódovaným duplicitním hodnotám v mark-upu jazyka XAML (Extensible Application Markup Language), ale jejich použití může být zdlouhavé. Každou hodnotu vlastnosti přiřadíte jednotlivě, což může mít za následek nepotřebné a podrobné XAML. V této lekci se dozvíte, jak seskupit několik nastavení do stylu, což vám může pomoct zpřehltit kód a lépe ho udržovat.
Jak prostředky můžou nepotřebné soubory XAML
Prostředek poskytuje hodnotu jedné vlastnosti. Použití velkého množství prostředků ale může vést k podrobnému kódu XAML. Předpokládejme, že chcete přizpůsobit vzhled tlačítek. Nejprve vytvoříte prostředky pro hodnoty, které potřebujete. Pak použijete každý prostředek na všechna tlačítka. Následující kód ukazuje, jak může mark-up XAML hledat dvě tlačítka.
<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}" />
Všimněte si, že na každém z tlačítek se nastavuje stejných pět vlastností. Použití prostředků eliminuje potřebu opakovaných pevně zakódovaných hodnot ve čtyřech z nich. Tento typ mark-up XAML se ale rychle obtížně čte. Pokud navíc nastavujete velký počet vlastností pro každý ovládací prvek, je snadné omylem vynechat jeden z nich, což vede k nekonzistence ve vzhledu ovládacích prvků. Řešením je vytvořit styl, který přiřadí všechny čtyři vlastnosti najednou.
Co je setter?
Setters jsou klíčové komponenty, které používáte k vytváření stylů.
Setter je kontejner pro dvojici vlastností/hodnoty. Setter si můžete představit jako reprezentaci příkazu přiřazení. Určíte, která vlastnost se má přiřadit, a hodnotu, která se má použít. V mark-upu XAML obvykle vytváříte objekty Setter . Následující příklad vytvoří Setter objekt pro TextColor vlastnost.
<Setter Property="TextColor" Value="White" />
Prostředek můžete použít pro hodnotu v setter, jak je znázorněno v následujícím kódu. Tato technika je skvělá, když chcete použít stejnou hodnotu ve více sadě setter.
<Setter Property="TextColor" Value="{StaticResource textColor}" />
Poznámka:
Hodnota vlastnosti, kterou zadáte v setter, musí být implementována jako bindable vlastnost. Všechny vlastnosti ovládacích prvků v rozhraní .NET MAUI, které končí příponou Property, jsou vázané vlastnosti. Pokud se pokoušíte použít vlastnost, jako je TextColor v setter, ujistěte se, že existuje odpovídající bindable vlastnost s názvem TextColorProperty pro tento ovládací prvek. V praxi se tímto způsobem implementují téměř všechny vlastnosti, které chcete použít ve svých setterech.
Co je styl?
Styl je kolekce setter cílených na konkrétní typ ovládacího prvku. .NET MAUI vyžaduje cílový typ, aby se zajistilo, že vlastnosti v tomto typu existují.
Následující kód ukazuje styl, který kombinuje čtyři hodnoty z předchozího příkladu. Všimněte si, že TargetType je nastavena na Tlačítko a všechny vlastnosti v setters jsou členy třídy Button . Tento styl nelze použít pro popisek, protože třída Label neobsahuje BorderColor nebo BorderWidth vlastnost.
<Style TargetType="Button">
<Setter Property="BackgroundColor" Value="#2A84D3" />
<Setter Property="BorderColor" Value="#1C5F9B" />
<Setter Property="BorderWidth" Value="3" />
<Setter Property="TextColor" Value="White" />
</Style>
Definování stylu
Styly obvykle definujete jako prostředky uvnitř objektu ResourceDictionary . Slovník prostředků usnadňuje použití stylu napříč více ovládacími prvky na stejné stránce nebo dokonce v celé aplikaci. Následující kód ukazuje, jak definovat styl jako prostředek uvnitř slovníku. Všimněte si, že styl má název pomocí vlastnosti x:Key . Pojmenování stylu umožňuje odkazovat na něj ze stránek XAML.
<ContentPage.Resources>
<Style x:Key="MyButtonStyle" TargetType="Button">
...
</Style>
</ContentPage.Resources>
Použití stylu
Styl připojíte k ovládacímu prvku přiřazením názvu vlastnosti Style . Přiřazení způsobí aplikaci každého objektu Setter ve stylu na cílový ovládací prvek. Následující kód ukazuje, jak použít styl tlačítka na dvě tlačítka.
<Button Text="OK" Style="{StaticResource MyButtonStyle}" />
<Button Text="Cancel" Style="{StaticResource MyButtonStyle}" />
V předchozím příkladu jste použili rozšíření mark-up StaticResource k připojení stylu k ovládacím prvkům. Tato technika je skvělá, když nepotřebujete změnit styl za běhu. Ale co když chcete implementovat něco jako dynamické motivy, kde se musí uživatelské rozhraní změnit? V tomto případě můžete k načtení stylu použít značkovací rozšíření DynamicResource.
<Button Text="Cancel" Style="{DynamicResource MyButtonStyle}" />
DynamicResource sleduje změnu vlastnosti x:Key ve slovníku prostředků. Pokud napíšete kód, který načte nový styl do ResourceDictionary se stejnou hodnotou x:Key , nový styl se automaticky použije v uživatelském rozhraní.
Použití implicitního stylu pro více ovládacích prvků
Předpokládejme, že uživatelské rozhraní má 50 tlačítek a chcete u nich použít stejný styl. S tím, co zatím víme, byste museli přiřadit vlastnost Style na každém tlačítku ručně. Není to těžké, ale je to pořád zdlouhavé.
Implicitní styl je styl, který přidáte do slovníku prostředků, aniž byste mu dali identifikátor x:Key. Implicitní styly se automaticky použijí na všechny ovládací prvky zadaného objektu TargetType .
Následující kód ukazuje předchozí příklad deklarovaný jako implicitní styl. Tento styl se použije u každého tlačítka na stránce.
<ContentPage.Resources>
<Style TargetType="Button">
<Setter Property="BackgroundColor" Value="Blue" />
<Setter Property="BorderColor" Value="Navy" />
...
</Style>
</ContentPage.Resources>
Důležité
Porovnávání implicitních stylů s ovládacími prvky vyžaduje přesnou shodu se zadaným typem TargetType. Ovládací prvky, které dědí z cílového typu, neobdrží styly. Chcete-li ovlivnit zděděné ovládací prvky, můžete nastavit Style.ApplyToDerivedTypes atribut True při definování stylu. Pokud chcete například použít styl pro typ tlačítka a mít to vliv na všechna tlačítka, která dědí z tlačítka (například ImageButton, RadioButton nebo vlastní typ, který vytvoříte), můžete použít takový styl.
<ContentPage.Resources>
<Style TargetType="Button"
ApplyToDerivedTypes="True">
<Setter Property="BackgroundColor" Value="Black" />
</Style>
</ContentPage.Resources>
Přepsání stylu
Styl si můžete představit jako poskytnutí sady výchozích hodnot pro ovládací prvky. Stávající styl se může blížit vašim požadavkům, ale obsahovat jednu nebo dvě zařízení, která nechcete. V takovém případě můžete použít styl a potom hodnotu přepsat nastavením vlastností přímo. Explicitní nastavení se použije za stylem, takže přepíše hodnotu ze stylu.
Předpokládejme, že chcete použít následující styl pro několik tlačítek na stránce.
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="BackgroundColor" Value="Blue" />
<Setter Property="BorderRadius" Value="10" />
<Setter Property="BorderWidth" Value="3" />
</Style>
Tento styl funguje pro všechna tlačítka s výjimkou tlačítka Zrušit, což vyžaduje červené pozadí. Stejný styl můžete použít pro tlačítko Storno, pokud také nastavíte vlastnost BackgroundColor přímo. Následující kód ukazuje, jak přepsat nastavení barvy.
<Button
Text="Cancel"
Style="{StaticResource MyButtonStyle}"
BackgroundColor="Red"
... />
Cílení na typ nadřazeného objektu
Předpokládejme, že chcete pro tlačítka a popisky použít vlastní barvu pozadí. Pro každý typ můžete vytvořit samostatné styly nebo můžete vytvořit jeden styl s typem TargetType nastaveným na VisualElement. Tato technika funguje, protože VisualElement je základní třídou pro Button i Label.
Následující kód ukazuje styl, který cílí na základní třídu, která se používá na dva různé odvozené typy.
<Style x:Key="MyVisualElementStyle" TargetType="VisualElement">
<Setter Property="BackgroundColor" Value="#2A84D3" />
</Style>
...
<Button Style="{StaticResource MyVisualElementStyle}" ... />
<Label Style="{StaticResource MyVisualElementStyle}" ... />
Tento příklad identifikuje styl pomocí x:Key a ovládacích prvků ho explicitně aplikují. Implicitní styl tady nefunguje, protože Typ cíle pro implicitní styl musí být přesná shoda s typem ovládacího prvku.
Použití BasedOn k dědění ze stylu
Předpokládejme, že chcete vytvořit soudržný vzhled uživatelského rozhraní. Rozhodnete se, že všechny ovládací prvky by měly používat konzistentní barvu pozadí. Nastavení barvy pozadí se pravděpodobně zobrazí ve více než jednom ze stylů. Následující kód zobrazuje dva styly s opakovaným setterem.
<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>
Dědičnost stylu můžete použít k určení duplicitního setteru do základního stylu. Chcete-li vytvořit odvozený styl, nastavte jeho BasedOn vlastnost odkazovat na základní styl. Nový styl dědí všechny settery ze základního stylu. Odvozený styl může také přidat nové settery nebo nahradit zděděné setter s tím, který obsahuje jinou hodnotu.
Následující kód ukazuje styly z předchozího příkladu refaktorované do hierarchie. Společné setter se zobrazí pouze v základním stylu, nikoli v opakování. Všimněte si použití rozšíření značkovacího jazyka StaticResource k vyhledání základního stylu. V této situaci nemůžete použít DynamicResource .
<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>
Hodnota TargetType základního a odvozeného stylu musí být kompatibilní. Aby byly styly kompatibilní, musí mít buď stejnou vlastnost TargetType , nebo TargetType odvozeného stylu je sestupný typ TargetType základního stylu.