Stavy vizuálů
Visual State Manager pro víceplatformní aplikace .NET (.NET MAUI) poskytuje strukturovaný způsob, jak provádět vizuální změny uživatelského rozhraní z kódu. Ve většině případů je uživatelské rozhraní aplikace definováno v jazyce XAML a tento XAML může obsahovat značky popisující, jak správce vizuálního stavu ovlivňuje vizuály uživatelského rozhraní.
Správce stavu vizuálu zavádí koncept stavů vizuálů. Zobrazení .NET MAUI, jako Button je například, může mít několik různých vzhledů vizuálů v závislosti na jeho základním stavu – ať už je zakázané, nebo stisknuté nebo má fokus vstupu. Toto jsou stavy tlačítka. Stavy vizuálů se shromažďují ve skupinách stavů vizuálů. Všechny stavy vizuálů ve skupině stavů vizuálu se vzájemně vylučují. Vizuální stavy i skupiny stavů vizuálů jsou identifikovány jednoduchými textovými řetězci.
Správce vizuálního stavu .NET MAUI definuje skupinu stavů vizuálu s názvem CommonStates
s následujícími stavy vizuálu:
- Normální
- Zakázáno
- Focused
- Selected
- Ukazatel myši
Stavy , , Focused
Disabled
a PointerOver
vizuály Normal
jsou podporovány ve všech třídách, které jsou odvozeny od VisualElement, což je základní třída pro View a Page. Kromě toho můžete také definovat vlastní skupiny stavů vizuálu a stavy vizuálů.
Výhodou použití Správce vizuálního stavu k definování vzhledu, nikoli přístupu k vizuálním prvkům přímo z kódu, je, že můžete řídit, jak vizuální prvky reagují zcela na jiný stav v XAML, což udržuje veškerý návrh uživatelského rozhraní na jednom místě.
Poznámka:
Triggery můžou také provádět změny vizuálů v uživatelském rozhraní na základě změn ve vlastnostech zobrazení nebo aktivaci událostí. Použití triggerů k řešení různých kombinací těchto změn ale může být matoucí. Ve Správci stavu vizuálu se vizuální stavy ve skupině stavů vizuálu vždy vzájemně vylučují. Aktuální stav je vždy jen jeden stav v každé skupině.
Běžné stavy vizuálů
Správce vizuálního stavu umožňuje zahrnout do souboru XAML značky, které můžou změnit vzhled zobrazení, pokud je zobrazení normální, zakázané, má fokus, je vybraný nebo má ukazatel myši, který na něj najede myší, ale ne stiskne. Ty se označují jako běžné státy.
Předpokládejme například, že máte Entry na stránce zobrazení a chcete, aby se vzhled vizuálu Entry změnil následujícími způsoby:
- Pokud Entry je tato možnost zakázaná Entry , měla by mít růžové pozadí.
- Normálně Entry by měl mít limetkové pozadí.
- Pokud Entry má vstupní fokus, měl by se rozbalit na dvojnásobek jeho normální výšky.
- Mělo Entry by mít světle modré pozadí, pokud má ukazatel myši, který na něj najede myší, ale ne stisknut.
Kód Visual State Manageru můžete připojit k jednotlivým zobrazením nebo ho můžete definovat ve stylu, pokud se vztahuje na více zobrazení.
Definování stavů vizuálů v zobrazení
Třída VisualStateManager
definuje připojenou VisualStateGroups
vlastnost, která slouží k připojení vizuálních stavů k zobrazení. Vlastnost VisualStateGroups
je typu VisualStateGroupList
, což je kolekce VisualStateGroup
objektů. Proto je podřízeným objektem VisualStateManager.VisualStateGroups
VisualStateGroup
připojené vlastnosti. Tento objekt definuje x:Name
atribut, který označuje název skupiny. VisualStateGroup
Případně třída definuje Name
vlastnost, kterou můžete místo toho použít. Další informace o připojených vlastnostech naleznete v části Připojené vlastnosti.
Třída VisualStateGroup
definuje vlastnost s názvem States
, což je kolekce VisualState objektů. States
je vlastnost VisualStateGroups
obsahu třídy, takže můžete zahrnout VisualState objekty jako podřízené objekty VisualStateGroup
. Každý VisualState objekt by měl být identifikován pomocí x:Name
nebo Name
.
Třída VisualState definuje vlastnost s názvem Setters
, což je kolekce Setter objektů. Jedná se o stejné Setter objekty, které používáte v objektu Style . Setters
není vlastnost VisualStateobsahu , takže je nutné zahrnout značky elementů vlastností pro Setters
vlastnost. Setter objekty by měly být vloženy jako podřízené položky Setters
. Každý Setter objekt označuje hodnotu vlastnosti, pokud je tento stav aktuální. Všechny vlastnosti odkazované objektem Setter musí být zajištěny vazebnou vlastností.
Důležité
Aby objekty vizuálního stavu Setter fungovaly správně, VisualStateGroup
musí obsahovat VisualState objekt pro Normal
stav. Pokud tento stav vizuálu neobsahuje žádné Setter objekty, měl by být zahrnut jako prázdný stav vizuálu (<VisualState Name="Normal" />
).
Následující příklad ukazuje vizuální stavy definované na:Entry
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Pink" />
</VisualState.Setters>
</VisualState>
<VisualState Name="PointerOver">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="LightBlue" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
</Entry>
Následující snímek obrazovky ukazuje čtyři definované stavy vizuálu Entry :
Entry Když je ve Normal
stavu, jeho pozadí je vápno. Když se Entry při zvýšení vstupu fokus velikost písma zdvojnásobí. Po zakázání Entry se pozadí změní na růžové. Když Entry získá vstupní fokus, nezachová pozadí vápna. Když ukazatel myši najede myší na Entrytlačítko , ale není stisknut, Entry pozadí se změní na světle modrou. Když Správce stavu vizuálu přepíná mezi stavy vizuálu, vlastnosti nastavené předchozím stavem nejsou nastaveny. Proto se vizuální stavy vzájemně vylučují.
Pokud chcete Entry , aby měl ve stavu vápno pozadí, přidejte do tohoto vizuálního Focused
stavu další Setter :
<VisualState Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
Definování stavů vizuálů ve stylu
Často je potřeba sdílet stejné vizuální stavy ve dvou nebo více zobrazeních. V tomto scénáři lze vizuální stavy definovat v objektu Style. Toho lze dosáhnout přidáním Setter objektu VisualStateManager.VisualStateGroups
pro vlastnost. Vlastnost obsahu objektu Setter je jeho Value
vlastnost, která může být proto zadána jako podřízený Setter objekt. Vlastnost VisualStateGroups
je typu VisualStateGroupList
, a proto podřízený Setter objekt je VisualStateGroupList
objekt, do kterého VisualStateGroup
lze přidat, který obsahuje VisualState objekty.
Následující příklad ukazuje implicitní styl pro definici Entry běžných vizuálních stavů:
<Style TargetType="Entry">
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Pink" />
</VisualState.Setters>
</VisualState>
<VisualState Name="PointerOver">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="LightBlue" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
Pokud je tento styl součástí slovníku prostředků na úrovni stránky, Style použije se objekt pro všechny Entry objekty na stránce. Proto všechny Entry objekty na stránce budou reagovat stejným způsobem na jejich vizuální stavy.
Vizuální stavy v .NET MAUI
Následující tabulka uvádí stavy vizuálů definované v rozhraní .NET MAUI:
Třída | Stavy | Další informace |
---|---|---|
Button | Pressed |
Stavy vizuálů tlačítek |
CarouselView | DefaultItem , CurrentItem , , PreviousItem NextItem |
Stavy vizuálu CarouselView |
CheckBox | IsChecked |
Stavy vizuálu CheckBox |
CollectionView | Selected |
Stavy vizuálu CollectionView |
ImageButton | Pressed |
Stavy vizuálu ImageButton |
RadioButton | Checked , Unchecked |
Stavy vizuálu RadioButton |
Switch | On , Off |
Přepnutí stavů vizuálů |
VisualElement | Normal , Disabled , , Focused PointerOver |
Běžné stavy |
Nastavení stavu u více prvků
Vpředchozíchch Je však také možné vytvořit vizuální stavy, které jsou připojeny k jednomu prvku, ale které nastaví vlastnosti na jiných prvcích ve stejném oboru. Vyhnete se tak opakování vizuálních stavů u každého prvku, na kterém stavy pracují.
Typ Setter má TargetName
vlastnost typu string
, která představuje cílový objekt, který Setter bude stav vizuálu manipulovat. TargetName
Pokud je vlastnost definována, Setter nastaví Property
objekt definovaný v TargetName
:Value
<Setter TargetName="label"
Property="Label.TextColor"
Value="Red" />
V tomto příkladu bude mít pojmenovaná Label label
vlastnost nastavena na Red
.TextColor
Při nastavování TargetName
vlastnosti je nutné zadat úplnou cestu k vlastnosti v .Property
Proto je vlastnost nastavena TextColor
na Label, Property
je zadána jako Label.TextColor
.
Poznámka:
Všechny vlastnosti odkazované objektem Setter musí být zajištěny vazebnou vlastností.
Následující příklad ukazuje, jak nastavit stav u více objektů z jedné skupiny stavů vizuálu:
<StackLayout>
<Label Text="What is the capital of France?" />
<Entry x:Name="entry"
Placeholder="Enter answer" />
<Button Text="Reveal answer">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal" />
<VisualState Name="Pressed">
<VisualState.Setters>
<Setter Property="Scale"
Value="0.8" />
<Setter TargetName="entry"
Property="Entry.Text"
Value="Paris" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Button>
</StackLayout>
V tomto příkladu Normal
je stav aktivní, když Button není stisknuto, a do pole lze zadat Entryodpověď . Stav Pressed
se stane aktivní při Button stisknutí a určuje, že jeho Scale
vlastnost bude změněna z výchozí hodnoty 1 na 0,8. Kromě toho bude Text
mít pojmenovaná Entry entry
vlastnost nastavena na Paříž. Výsledkem je proto, že když Button je stisknuto, bude o něco menší a Entry zobrazí Paříž:
Po Button vydání se pak škáluje na výchozí hodnotu 1 a Entry zobrazí všechny dříve zadané texty.
Důležité
Cesty vlastností nejsou podporovány v Setter elementech, které určují TargetName
vlastnost.
Definování stavů vlastních vizuálů
Vlastní stavy vizuálů je možné implementovat tak, že je definujete tak, jak definujete stavy vizuálů pro běžné stavy, ale s názvy podle vlastního výběru a voláním VisualStateManager.GoToState
metody aktivujte stav.
Následující příklad ukazuje, jak použít Visual State Manager pro ověřování vstupu:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="VsmDemos.VsmValidationPage"
Title="VSM Validation">
<StackLayout x:Name="stackLayout"
Padding="10, 10">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="ValidityStates">
<VisualState Name="Valid">
<VisualState.Setters>
<Setter TargetName="helpLabel"
Property="Label.TextColor"
Value="Transparent" />
<Setter TargetName="entry"
Property="Entry.BackgroundColor"
Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Invalid">
<VisualState.Setters>
<Setter TargetName="entry"
Property="Entry.BackgroundColor"
Value="Pink" />
<Setter TargetName="submitButton"
Property="Button.IsEnabled"
Value="False" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Label Text="Enter a U.S. phone number:"
FontSize="18" />
<Entry x:Name="entry"
Placeholder="555-555-5555"
FontSize="18"
Margin="30, 0, 0, 0"
TextChanged="OnTextChanged" />
<Label x:Name="helpLabel"
Text="Phone number must be of the form 555-555-5555, and not begin with a 0 or 1" />
<Button x:Name="submitButton"
Text="Submit"
FontSize="18"
Margin="0, 20"
VerticalOptions="Center"
HorizontalOptions="Center" />
</StackLayout>
</ContentPage>
V tomto příkladu jsou vizuální stavy připojeny k StackLayouta existují dva vzájemně se vylučující stavy pojmenované Valid
a Invalid
. Pokud neobsahuje Entry platné telefonní číslo, aktuální stav je Invalid
a proto Entry má růžové pozadí, druhá Label je viditelná a je zakázaná Button . Po zadání platného telefonního čísla se stane Valid
aktuální stav . Získá Entry vápno pozadí, druhý Label zmizí a Button je nyní povolen:
Soubor kódu je zodpovědný za zpracování TextChanged
události z objektu Entry. Obslužná rutina používá regulární výraz k určení, jestli je vstupní řetězec platný nebo ne. Metoda GoToState
v souboru kódu volá statickou VisualStateManager.GoToState
metodu objektu StackLayout :
public partial class VsmValidationPage : ContentPage
{
public VsmValidationPage()
{
InitializeComponent();
GoToState(false);
}
void OnTextChanged(object sender, TextChangedEventArgs args)
{
bool isValid = Regex.IsMatch(args.NewTextValue, @"^[2-9]\d{2}-\d{3}-\d{4}$");
GoToState(isValid);
}
void GoToState(bool isValid)
{
string visualState = isValid ? "Valid" : "Invalid";
VisualStateManager.GoToState(stackLayout, visualState);
}
}
V tomto příkladu GoToState
je volána metoda z konstruktoru pro inicializaci stavu. Vždy by měl existovat aktuální stav. Kód za soubor pak volá VisualStateManager.GoToState
, s názvem stavu, na objektu, který definuje stavy vizuálu.
Triggery vizuálního stavu
Vizuální stavy podporují triggery stavu, což je specializovaná skupina triggerů, které definují podmínky, za kterých VisualState se mají použít.
Aktivační události stavu se přidají do StateTriggers kolekce objektu VisualState. Tato kolekce může obsahovat jednu aktivační událost stavu nebo více aktivačních událostí stavu. A VisualState se použije, když jsou aktivní všechny aktivační události stavu v kolekci.
Při použití aktivačních událostí stavu k řízení vizuálních stavů používá .NET MAUI následující pravidla priority k určení, která aktivační událost (a odpovídající VisualState) bude aktivní:
- Jakákoli aktivační událost, která je odvozena od StateTriggerBase.
- Aktivované AdaptiveTrigger z důvodu MinWindowWidth splnění podmínky.
- Aktivované AdaptiveTrigger z důvodu MinWindowHeight splnění podmínky.
Pokud je více aktivačních událostí současně aktivních (například dva vlastní triggery), má přednost první aktivační událost deklarovaná v kódu.
Další informace o aktivačních událostech stavu najdete v tématu Aktivační události stavu.