Xamarin.Forms Visual State Manager
Pomocí Visual State Manageru proveďte změny elementů XAML na základě stavů vizuálů nastavených z kódu.
Visual State Manager (VSM) 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 obsahuje revize popisující, jak Visual State Manager ovlivňuje vizuály uživatelského rozhraní.
Virtuální počítač zavádí koncept vizuálních stavů. Zobrazení Xamarin.Forms , jako je například, Button
může mít několik různých vizuálních vzhledů v závislosti na jeho základním stavu – bez ohledu na to, jestli 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 vizuální stavy 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.
Xamarin.Forms Visual State Manager definuje jednu skupinu stavů vizuálu s názvem CommonStates s následujícími stavy vizuálu:
- "Normální"
- Zakázáno
- "Prioritní"
- "Selected" (Vybráno)
Tato skupina stavů vizuálu je podporována pro všechny třídy odvozené z VisualElement
, což je základní třída pro View
a Page
.
Můžete také definovat vlastní skupiny stavů vizuálu a stavy vizuálů, jak ukazuje tento článek.
Poznámka
Xamarin.Forms vývojáři, kteří jsou obeznámeni s aktivačními událostmi , vědí, že 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 spouštění událostí. Použití triggerů k řešení různých kombinací těchto změn se ale může stát poměrně matoucí. Visual State Manager byl zaveden v Windows prostředích založených na XAML, aby se zmírnit nejasnost vyplývající z kombinací vizuálních stavů. U virtuálního počítače se vizuální stavy ve skupině stavů vizuálu vždy vzájemně vylučují. Vždy je aktuální stav pouze jeden stav v každé skupině.
Běžné stavy
Visual State Manager umožňuje zahrnout do souboru XAML revize, které můžou změnit vzhled vizuálu zobrazení, pokud je zobrazení normální nebo zakázané nebo má vstupní fokus. Tyto stavy se označují jako společ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ím způsobem:
- Pokud
Entry
je vypnutý, měl by mít růžové pozadíEntry
. - Měl
Entry
by mít normálně vápno. - Pokud
Entry
má vstupní fokus, měl by se zvětšit na dvojnásobek jeho normální výšky.
Kód virtuálního počítače můžete připojit k individuálnímu zobrazení nebo ho můžete definovat ve stylu, pokud se vztahuje na více zobrazení. Následující dvě části popisují tyto přístupy.
Revize virtuálního počítače v zobrazení
Pokud chcete připojit značky virtuálního počítače k Entry
zobrazení, nejprve oddělte Entry
počáteční a koncové značky:
<Entry FontSize="18">
</Entry>
Má explicitní velikost písma, protože jeden ze stavů použije FontSize
vlastnost k zdvojnásobení velikosti textu v souboru Entry
.
Dále vložte VisualStateManager.VisualStateGroups
značky mezi tyto značky:
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
</VisualStateManager.VisualStateGroups>
</Entry>
VisualStateGroups
je připojená bindable vlastnost definovaná VisualStateManager
třídou. (Další informace o připojených svázatelných vlastnostech najdete v článku Připojené vlastnosti.) Tímto způsobem je VisualStateGroups
vlastnost připojena k objektu Entry
.
Vlastnost VisualStateGroups
je typu VisualStateGroupList
, což je kolekce VisualStateGroup
objektů. VisualStateManager.VisualStateGroups
Do značek vložte dvojici VisualStateGroup
značek pro každou skupinu stavů vizuálů, které chcete zahrnout:
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Entry>
Všimněte si, že VisualStateGroup
značka má x:Name
atribut označující název skupiny. Třída VisualStateGroup
definuje Name
vlastnost, kterou můžete místo toho použít:
<VisualStateGroup Name="CommonStates">
Můžete použít buď x:Name
nebo Name
ne oba ve stejném prvku.
Třída VisualStateGroup
definuje vlastnost s názvem States
, což je kolekce VisualState
objektů. States
je vlastnostVisualStateGroups
obsahu, abyste mohli značky zahrnout VisualState
přímo mezi VisualStateGroup
značky. (Vlastnosti obsahu jsou popsány v článku Základní syntaxe XAML.)
Dalším krokem je zahrnutí dvojice značek pro každý stav vizuálu v této skupině. Můžete je také identifikovat pomocí x:Name
nebo Name
:
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
</VisualState>
<VisualState x:Name="Focused">
</VisualState>
<VisualState x:Name="Disabled">
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Entry>
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 obsahu , takže je nutné zahrnout značky elementů VisualState
vlastností pro Setters
vlastnost:
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Focused">
<VisualState.Setters>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Entry>
Nyní můžete vložit jeden nebo více Setter
objektů mezi každou dvojici Setters
značek. Jedná se o Setter
objekty, které definují stavy vizuálů popsané výše:
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Pink" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Entry>
Každá Setter
značka označuje hodnotu konkrétní vlastnosti, pokud je tento stav aktuální. Každá vlastnost odkazovaná objektem Setter
musí být zajištěna vazebnou vlastností.
Značky podobné tomu jsou základem virtuálního počítače na stránce Zobrazení v ukázkovém programu VsmDemos . Stránka obsahuje tři Entry
zobrazení, ale pouze druhá má kód virtuálního počítače připojený k němu:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:VsmDemos"
x:Class="VsmDemos.MainPage"
Title="VSM Demos">
<StackLayout>
<StackLayout.Resources>
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
</Style>
<Style TargetType="Label">
<Setter Property="Margin" Value="20, 30, 20, 0" />
<Setter Property="FontSize" Value="Large" />
</Style>
</StackLayout.Resources>
<Label Text="Normal Entry:" />
<Entry />
<Label Text="Entry with VSM: " />
<Entry>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Pink" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Entry.Triggers>
<DataTrigger TargetType="Entry"
Binding="{Binding Source={x:Reference entry3},
Path=Text.Length}"
Value="0">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Entry.Triggers>
</Entry>
<Label Text="Entry to enable 2nd Entry:" />
<Entry x:Name="entry3"
Text=""
Placeholder="Type something to enable 2nd Entry" />
</StackLayout>
</ContentPage>
Všimněte si, že druhá Entry
má DataTrigger
také součást své Trigger
kolekce. To způsobí, že Entry
bude zakázána, dokud se něco nenapište do třetí Entry
. Tady je stránka při spuštění v iOSu, Androidu a Univerzální platforma Windows (UPW):
Aktuální stav vizuálu je "Zakázáno", takže pozadí druhé Entry
je růžové na obrazovkách iOS a Androidu. Implementace Entry
UPW neumožňuje nastavení barvy pozadí, pokud je zakázaná Entry
.
Když do třetího Entry
zadáte nějaký text, druhý Entry
se přepne do stavu Normální a pozadí je teď vápno:
Když se dotknete druhého Entry
, dostane vstupní fokus. Přepne do stavu Prioritní a rozbalí se na dvojnásobek jeho výšky:
Všimněte si, že Entry
při získání vstupního fokusu se neuchová pozadí vápna. Vzhledem k tomu, že Visual State Manager přepíná mezi stavy vizuálu, vlastnosti nastavené předchozím stavem nejsou nastaveny. Mějte na paměti, že vizuální stavy se vzájemně vylučují. Stav Normální neznamená pouze to, že Entry
je povolená. Znamená to, že Entry
je povolená a nemá fokus vstupu.
Pokud chcete Entry
mít vápenkové pozadí ve stavu Prioritní, přidejte do tohoto vizuálního stavu další Setter
:
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
Aby tyto Setter
objekty správně fungovaly, VisualStateGroup
musí obsahovat VisualState
objekty pro všechny stavy v této skupině. Pokud existuje stav vizuálu, který nemá žádné Setter
objekty, zahrňte ho přesto jako prázdnou značku:
<VisualState x:Name="Normal" />
Revize Visual State Manageru ve stylu
Často je potřeba sdílet stejné revize Visual State Manageru mezi dvěma nebo více zobrazeními. V tomto případě budete chtít kód vložit do Style
definice.
Tady je existující implicitní Style
pro Entry
prvky na stránce zobrazení virtuálního počítače:
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
</Style>
Přidejte Setter
značky pro připojenou VisualStateManager.VisualStateGroups
vlastnost bindable:
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
</Setter>
</Style>
Vlastnost Setter
obsahu je Value
, takže hodnotu Value
vlastnosti lze zadat přímo v rámci těchto značek. Tato vlastnost je typu VisualStateGroupList
:
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
</VisualStateGroupList>
</Setter>
</Style>
Do těchto značek můžete zahrnout jeden z více VisualStateGroup
objektů:
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
Zbývající kód virtuálního počítače je stejný jako předtím.
Tady je stránka VSM ve stylu zobrazující kompletní revize virtuálního počítače:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="VsmDemos.VsmInStylePage"
Title="VSM in Style">
<StackLayout>
<StackLayout.Resources>
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Pink" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="Label">
<Setter Property="Margin" Value="20, 30, 20, 0" />
<Setter Property="FontSize" Value="Large" />
</Style>
</StackLayout.Resources>
<Label Text="Normal Entry:" />
<Entry />
<Label Text="Entry with VSM: " />
<Entry>
<Entry.Triggers>
<DataTrigger TargetType="Entry"
Binding="{Binding Source={x:Reference entry3},
Path=Text.Length}"
Value="0">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Entry.Triggers>
</Entry>
<Label Text="Entry to enable 2nd Entry:" />
<Entry x:Name="entry3"
Text=""
Placeholder="Type something to enable 2nd Entry" />
</StackLayout>
</ContentPage>
Teď všechna Entry
zobrazení na této stránce reagují stejným způsobem jako jejich vizuální stavy. Všimněte si také, že stav Prioritní teď obsahuje sekundu Setter
, která dává každému Entry
vápno pozadí také v případě, že má vstupní fokus:
Stavy vizuálů v Xamarin.Forms
Následující tabulka uvádí stavy vizuálů, které jsou definovány v Xamarin.Forms:
Třída | Stavy | Další informace |
---|---|---|
Button |
Pressed |
Stavy vizuálu tlačítka |
CheckBox |
IsChecked |
Stavy vizuálu CheckBox |
CarouselView |
DefaultItem , CurrentItem , PreviousItem , NextItem |
Stavy vizuálu CarouselView |
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 , Selected |
Běžné stavy |
Každý z těchto stavů je přístupný prostřednictvím skupiny stavů vizuálu s názvem CommonStates
.
Kromě toho CollectionView
implementuje Selected
stav. Další informace naleznete v tématu Změna barvy vybrané položky.
Nastavení stavu u více prvků
V předchozích příkladech byly vizuální stavy připojeny k jednomu elementu a provozovány na nich. Je však také možné vytvořit vizuální stavy, které jsou připojeny k jednomu prvku, ale které nastavují vlastnosti u jiných prvků ve stejném oboru. Tím se zabrání opakování vizuálních stavů u každého prvku, na kterých stavy pracují.
Typ Setter
má TargetName
vlastnost typu string
, která představuje cílový prvek, který Setter
bude pro vizuální stav manipulovat. TargetName
Pokud je vlastnost definována, Setter
nastaví Property
element 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
Label
na , Property
je zadána jako Label.TextColor
.
Poznámka
Jakákoli vlastnost odkazovaná objektem Setter
musí být zajištěna vazbou vlastnost.
Virtuální počítač se stránkou Setter TargetName v ukázce VsmDemos ukazuje, jak nastavit stav u více prvků z jedné skupiny stavů vizuálu. Soubor XAML se skládá z StackLayout
elementu, znaku Label
Entry
a :Button
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="VsmDemos.VsmSetterTargetNamePage"
Title="VSM with Setter TargetName">
<StackLayout Margin="10">
<Label Text="What is the capital of France?" />
<Entry x:Name="entry"
Placeholder="Enter answer" />
<Button Text="Reveal answer">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x: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>
</ContentPage>
Značka VSM je připojena k sadě StackLayout
. Existují dva vzájemně se vylučující stavy s názvem "Normal" a "Pressed", přičemž každý stav obsahuje VisualState
značky.
Stav "Normální" je aktivní, když Button
není stisknutá, a odpověď na otázku lze zadat:
Při stisknutí tlačítka se stav "Stisknuto" aktivuje Button
:
"Pressed" VisualState
určuje, že když Button
je stisknuto, jeho Scale
vlastnost bude změněna z výchozí hodnoty 1 na 0,8. Kromě toho bude mít pojmenovaná Entry
entry
Text
vlastnost nastavena na Paříž. Výsledek je proto takový, že když Button
je stisknuto, přeškálí se na o něco menší a zobrazí Entry
Paříž. Když se pak Button
uvolní, přeškálí se na výchozí hodnotu 1 a Entry
zobrazí všechny dříve zadané texty.
Důležité
Cesty k vlastnostem nejsou aktuálně podporovány v Setter
prvkách, které určují TargetName
vlastnost.
Definování vlastních stavů vizuálů
Každá třída, která je odvozena od VisualElement
, podporuje běžné stavy Normal, Prioritní a Disabled. Kromě toho CollectionView
třída podporuje stav "Selected". Třída interně rozpozná, VisualElement
kdy se aktivuje nebo zakáže, nebo jestli je fokusovaná, a zavolá statickou VisualStateManager.GoToState
metodu:
VisualStateManager.GoToState(this, "Focused");
Toto je jediný kód Visual State Manageru, který najdete ve VisualElement
třídě. Vzhledem k tomu GoToState
, že je volána pro každý objekt založený na každé třídě, která je odvozena z VisualElement
, můžete použít Visual State Manager s libovolným VisualElement
objektem k reakci na tyto změny.
Zajímavé je, že název skupiny stavů vizuálu "CommonStates" není explicitně odkazován v VisualElement
. Název skupiny není součástí rozhraní API pro Správce stavu vizuálu. V rámci jednoho ze dvou ukázkových programů zobrazených zatím můžete změnit název skupiny z commonstates na cokoli jiného a program bude fungovat. Název skupiny je pouze obecný popis stavů v této skupině. Implicitně se rozumí tomu, že vizuální stavy v libovolné skupině se vzájemně vylučují: Jeden stav a pouze jeden stav je kdykoli aktuální.
Pokud chcete implementovat vlastní stavy vizuálů, budete muset volat VisualStateManager.GoToState
z kódu. Nejčastěji budete volat ze souboru kódu třídy stránky.
Stránka Ověření virtuálního počítače v ukázce VsmDemos ukazuje, jak používat Visual State Manager ve spojení se vstupním ověřováním. Soubor XAML se skládá ze StackLayout
dvou Label
prvků:Entry
Button
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
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="Large" />
<Entry x:Name="entry"
Placeholder="555-555-5555"
FontSize="Large"
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="Large"
Margin="0, 20"
VerticalOptions="Center"
HorizontalOptions="Center" />
</StackLayout>
</ContentPage>
Značka VSM je připojená StackLayout
k (pojmenované stackLayout
). Existují dva vzájemně se vylučující stavy s názvem "Valid" a "Invalid", přičemž každý stav obsahuje VisualState
značky.
Entry
Pokud číslo neobsahuje platné telefonní číslo, aktuální stav je neplatný, takže Entry
má růžové pozadí, druhá Label
je viditelná a Button
je zakázaná:
Po zadání platného telefonního čísla se aktuální stav změní na Platné. Získá Entry
vápno pozadí, druhý Label
zmizí a Button
teď je povolen:
Soubor s kódem je zodpovědný za zpracování TextChanged
události z Entry
souboru . Obslužná rutina používá regulární výraz k určení, jestli je vstupní řetězec platný nebo ne. Metoda v souboru kódu s názvem volá GoToState
statickou VisualStateManager.GoToState
metodu pro 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šimněte si také, že GoToState
metoda je volána z konstruktoru pro inicializaci stavu. Vždy by měl existovat aktuální stav. Ale nikde v kódu neexistuje žádný odkaz na název skupiny stavů vizuálu, ačkoli je odkazován v XAML jako "ValidationStates" pro účely srozumitelnosti.
Všimněte si, že soubor kódu za kódem musí vzít v úvahu pouze objekt na stránce, který definuje stavy vizuálu, a volat VisualStateManager.GoToState
pro tento objekt. Důvodem je, že oba vizuály cílí na více objektů na stránce.
Možná vás zajímá: Pokud soubor kódu za kódem musí odkazovat na objekt na stránce, která definuje vizuální stavy, proč nemůže soubor kódu jednoduše získat přístup k tomuto a dalším objektům přímo? Určitě by to mohlo. Výhodou použití virtuálního počítače je ale to, že můžete řídit, jak vizuální prvky reagují na jiný stav zcela v XAML, což udržuje veškerý návrh uživatelského rozhraní na jednom místě. Tím se zabrání nastavení vzhledu vizuálu tím, že přistupujete k vizuálním prvkům přímo z kódu.
Triggery stavu vizuálu
Vizuální stavy podporují triggery stavu, což je specializovaná skupina aktivačních událostí, které definují podmínky, za kterých VisualState
se má 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 triggery stavu v kolekci.
Při použití aktivačních událostí stavu k řízení vizuálních stavů pomocí následujících pravidel priority určíte Xamarin.Forms , která aktivační událost (a odpovídající VisualState
) bude aktivní:
- Všechny aktivační události, které jsou odvozeny od
StateTriggerBase
. - Aktivovaný
AdaptiveTrigger
z důvoduMinWindowWidth
splnění podmínky. - Aktivovaný
AdaptiveTrigger
z důvoduMinWindowHeight
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 revizích.
Další informace o aktivačních událostech stavu najdete v tématu Aktivační události stavu.
Použití Visual State Manageru pro adaptivní rozložení
Xamarin.Forms Aplikace spuštěná na telefonu se obvykle dá zobrazit v poměru stran na výšku nebo na šířku a Xamarin.Forms program spuštěný na ploše se dá změnit tak, aby předpokládal mnoho různých velikostí a poměrů stran. Dobře navržená aplikace může pro tyto různé faktory formuláře stránky nebo okna zobrazovat svůj obsah odlišně.
Tato technika se někdy označuje jako adaptivní rozložení. Vzhledem k tomu, že adaptivní rozložení zahrnuje pouze vizuály programu, je to ideální aplikace Správce stavu vizuálu.
Jednoduchým příkladem je aplikace, která zobrazuje malou kolekci tlačítek, která ovlivňují obsah aplikace. V režimu na výšku se tato tlačítka můžou zobrazit ve vodorovném řádku v horní části stránky:
V režimu na šířku se pole tlačítek může přesunout na jednu stranu a zobrazit ve sloupci:
Shora dolů program běží na Univerzální platforma Windows, Androidu a iOSu.
Stránka adaptivního rozložení virtuálního počítače v ukázce VsmDemos definuje skupinu s názvem "OrientationStates" se dvěma vizuálními stavy s názvem "Na výšku" a "Na šířku". (Složitější přístup může být založený na několika různých šířkách stránek nebo oken.)
Značky VSM se vyskytují na čtyřech místech v souboru XAML. Pojmenovaný StackLayout
mainStack
obsahuje nabídku i obsah, což je Image
prvek. To StackLayout
by mělo mít svislou orientaci v režimu na výšku a vodorovnou orientaci v režimu na šířku:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="VsmDemos.VsmAdaptiveLayoutPage"
Title="VSM Adaptive Layout">
<StackLayout x:Name="mainStack">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="OrientationStates">
<VisualState Name="Portrait">
<VisualState.Setters>
<Setter Property="Orientation" Value="Vertical" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Landscape">
<VisualState.Setters>
<Setter Property="Orientation" Value="Horizontal" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ScrollView x:Name="menuScroll">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="OrientationStates">
<VisualState Name="Portrait">
<VisualState.Setters>
<Setter Property="Orientation" Value="Horizontal" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Landscape">
<VisualState.Setters>
<Setter Property="Orientation" Value="Vertical" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<StackLayout x:Name="menuStack">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="OrientationStates">
<VisualState Name="Portrait">
<VisualState.Setters>
<Setter Property="Orientation" Value="Horizontal" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Landscape">
<VisualState.Setters>
<Setter Property="Orientation" Value="Vertical" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<StackLayout.Resources>
<Style TargetType="Button">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup Name="OrientationStates">
<VisualState Name="Portrait">
<VisualState.Setters>
<Setter Property="HorizontalOptions" Value="CenterAndExpand" />
<Setter Property="Margin" Value="10, 5" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Landscape">
<VisualState.Setters>
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="Margin" Value="10" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</StackLayout.Resources>
<Button Text="Banana"
Command="{Binding SelectedCommand}"
CommandParameter="Banana.jpg" />
<Button Text="Face Palm"
Command="{Binding SelectedCommand}"
CommandParameter="FacePalm.jpg" />
<Button Text="Monkey"
Command="{Binding SelectedCommand}"
CommandParameter="monkey.png" />
<Button Text="Seated Monkey"
Command="{Binding SelectedCommand}"
CommandParameter="SeatedMonkey.jpg" />
</StackLayout>
</ScrollView>
<Image x:Name="image"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand" />
</StackLayout>
</ContentPage>
Vnitřní ScrollView
název menuScroll
a pojmenovaná StackLayout
menuStack
implementace nabídky tlačítek. Orientace těchto rozložení je opakem mainStack
. Nabídka by měla být vodorovná v režimu na výšku a svisle v režimu na šířku.
Čtvrtá část značek VSM je implicitní styl tlačítek samotných. Tato sada VerticalOptions
značek a HorizontalOptions
Margin
vlastnosti specifické pro orientaci na výšku a na šířku.
Soubor s kódem nastaví BindingContext
vlastnost menuStack
pro implementaci Button
příkazů a také připojí obslužnou rutinu SizeChanged
k události stránky:
public partial class VsmAdaptiveLayoutPage : ContentPage
{
public VsmAdaptiveLayoutPage ()
{
InitializeComponent ();
SizeChanged += (sender, args) =>
{
string visualState = Width > Height ? "Landscape" : "Portrait";
VisualStateManager.GoToState(mainStack, visualState);
VisualStateManager.GoToState(menuScroll, visualState);
VisualStateManager.GoToState(menuStack, visualState);
foreach (View child in menuStack.Children)
{
VisualStateManager.GoToState(child, visualState);
}
};
SelectedCommand = new Command<string>((filename) =>
{
image.Source = ImageSource.FromResource("VsmDemos.Images." + filename);
});
menuStack.BindingContext = this;
}
public ICommand SelectedCommand { private set; get; }
}
Obslužná rutina SizeChanged
volá VisualStateManager.GoToState
tyto dva StackLayout
prvky a ScrollView
potom prochází podřízené prvky menuStack
volání VisualStateManager.GoToState
Button
prvků.
Může se zdát, že soubor s kódem za kódem může zpracovávat změny orientace přímo nastavením vlastností prvků v souboru XAML, ale Správce vizuálního stavu je rozhodně strukturovanější přístup. Všechny vizuály se uchovávají v souboru XAML, kde se snadněji prověřují, udržují a upravují.
Visual State Manager s Xamarin.University
Xamarin.Forms 3.0 Video visual state manageru