Xamarin.Forms Manažer vizuálního stavu

Ukázka stažení Stažení ukázky

Pomocí Správce vizuálního stavu můžete měnit prvky XAML na základě vizuálních stavů, které jsou nastaveny z kódu.

Správce vizuálního stavu (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 kód XAML obsahuje značky popisující, jak má manažer vizuálního stavu vliv na vizuály uživatelského rozhraní.

VSM zavádí koncept vizuálních stavů. Zobrazení, jako Xamarin.Forms 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 – ať už je zakázané, stisknuté nebo má vstupní fokus. Toto jsou stavy tlačítka.

Vizuální stavy se shromažďují ve skupinách vizuálních stavů. Všechny vizuální stavy v rámci skupiny vizuálních stavů se vzájemně vylučují. Mezi vizuálními stavy a skupinami vizuálních stavů se identifikují jednoduché textové řetězce.

Xamarin.FormsSprávce vizuálních stavů definuje jednu skupinu vizuálů s názvem "CommonStates" s následujícími vizuálními stavy:

  • Běžnou
  • Zabezpečen
  • Zaměřil
  • Vyberte

Tato skupina vizuálních stavů je podporována pro všechny třídy, které jsou odvozeny z VisualElement , což je základní třída pro View a Page .

Můžete také definovat vlastní skupiny a vizuální stavy, jak je znázorněno v tomto článku.

Poznámka

Xamarin.Forms Vývojáři, kteří jsou obeznámeni s Xamarin.Forms , jsou vědomi, že triggery mohou také provádět změny vizuálů v uživatelském rozhraní na základě změn vlastností zobrazení nebo při vyvolávání událostí. Použití triggerů k tomu, aby bylo možné pracovat s různými kombinacemi těchto změn, však může být poměrně matoucí. v minulosti byl manažer vizuálního stavu představený v Windows prostředích založených na XAML, aby se zmírnila nejasnost vyplývající z kombinací vizuálních stavů. V VSM jsou vizuální stavy v rámci skupiny vizuálních stavů vždy vzájemně exkluzivní. V každém okamžiku je aktuálním stavem pouze jeden stav v každé skupině.

Běžné stavy

Manažer vizuálního stavu umožňuje zahrnout značku do souboru XAML, který může změnit vzhled zobrazení, pokud je zobrazení normální nebo zakázané nebo má fokus vstupu. Ty se označují jako běžné stavy.

Předpokládejme například, že máte Entry zobrazení na stránce a chcete, aby se vzhled vizuálu Entry změnil následujícími způsoby:

  • EntryPokud je zakázaný, měl by být na růžovém pozadí Entry .
  • EntryMělo by normálně mít normální pozadí.
  • EntryPokud má vstupní fokus, měl by se rozšířit na dvojnásobek normální výšky.

Můžete připojit značku VSM k individuálnímu zobrazení nebo ho můžete definovat ve stylu, pokud se vztahuje na více zobrazení. Následující dva oddíly tyto přístupy popisují.

VSM značky zobrazení

Chcete-li připojit VSM značky k Entry zobrazení, nejprve oddělte Entry do počáteční a koncové značky:

<Entry FontSize="18">

</Entry>

Je dána explicitní velikost písma, protože jeden ze stavů bude používat FontSize vlastnost k dvojnásobku velikosti textu v Entry .

V dalším kroku vložte VisualStateManager.VisualStateGroups značky mezi tyto značky:

<Entry FontSize="18">
    <VisualStateManager.VisualStateGroups>

    </VisualStateManager.VisualStateGroups>
</Entry>

VisualStateGroups je připojená vlastnost s možností vazby definovaná VisualStateManager třídou. (Další informace o připojených vlastnostech s možností vazby najdete v článku připojené vlastnosti.) To je způsob, jakým VisualStateGroups je vlastnost připojena k Entry objektu.

VisualStateGroupsVlastnost je typu VisualStateGroupList , což je kolekce VisualStateGroup objektů. V rámci VisualStateManager.VisualStateGroups značek vložte dvojici VisualStateGroup značek pro každou skupinu vizuálních stavů, 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, který určuje název skupiny. VisualStateGroupTřída definuje Name vlastnost, kterou můžete použít místo toho:

<VisualStateGroup Name="CommonStates">

x:NameVe stejném elementu můžete použít buď nebo, Name ale ne obojí.

VisualStateGroupTřída definuje vlastnost s názvem Xamarin_Forms VisualStateGroup _VisualStateGroup_States "data-LINKTYPE =" absolutní cesta ">States , což je kolekce VisualState objektů. States je States , VisualStateGroups takže můžete zahrnout VisualState značky přímo mezi VisualStateGroup značky. (Vlastnosti obsahu jsou popsány v článku základní syntaxe jazyka XAML.)

Dalším krokem je zahrnutí dvojice značek pro každý vizuální stav v dané 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>

VisualStatedefinuje vlastnost s názvem Xamarin_Forms VisualState _VisualState_Setters "data-LINKTYPE =" absolutní cesta ">Setters , což je kolekce Setter objektů. Jedná se o stejné Setter objekty, které používáte v Style objektu.

Setters není Setters obsahu VisualState pro, takže je nutné zahrnout značky elementu vlastnosti 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 jednotlivé páry Setters značek. Jedná se o Setter objekty, které definují výše popsané vizuální stavy:

<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 aktuální stav. Jakákoliv vlastnost, na kterou se odkazuje Setter objekt, musí být zálohovaná vlastností BIND.

Podobným způsobem je, že je základem stránky VSM on View v ukázkovém programu VsmDemos . Stránka obsahuje tři Entry zobrazení, ale k ní je připojen pouze druhý kód VSM:

<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á také DataTrigger jako součást své Trigger kolekce. To způsobí, že bude Entry zakázaný, dokud se do třetího nezadáte něco Entry . tady je stránka při spuštění běžící v iOS, androidu a Univerzální platforma Windows (UWP):

VSM zobrazení: zakázané .

Aktuální stav vizuálu je "zakázáno", takže pozadí druhé Entry je na obrazovkách iOS a Android růžové. Implementace UWP pro Entry nepovoluje nastavení barvy pozadí, pokud Entry je zakázaná.

Když do třetího textu zadáte nějaký text Entry , druhý se Entry přepne do stavu "normální" a pozadí je nyní vápno:

VSM v zobrazení: normální

Při dotyku s druhým Entry získá fokus vstupu. Přepne do stavu "zaměření" a rozbalí se na dvojnásobek výšky:

VSM pro zobrazení: prioritní

Všimněte si, že Entry při získání fokusu vstupu neuchovává pozadí na vápně. Protože vizuální správce stavů přepíná mezi vizuálními stavy, vlastnosti nastavené v předchozím stavu se nezmění. Pamatujte, že vizuální stavy se vzájemně vylučují. Stav "normální" neznamená pouze to, že Entry je povolen. To znamená, že Entry je povolen a nemá vstupní fokus.

Pokud chcete Entry , aby měl na pozadí vápno ve stavu "zaměření", přidejte další Setter do tohoto vizuálního stavu:

<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 dané skupině. Pokud je vizuální stav, který neobsahuje žádné Setter objekty, zahrňte ho jako prázdnou značku:

<VisualState x:Name="Normal" />

Kód manažera vizuálního stavu ve stylu

Je často nutné sdílet stejný kód manažera vizuálního stavu mezi dvěma nebo více zobrazeními. V takovém případě budete chtít značku vložit do Style definice.

Tady je existující implicitní Style pro Entry prvky na stránce Style :

<Style TargetType="Entry">
    <Setter Property="Margin" Value="20, 0" />
    <Setter Property="FontSize" Value="18" />
</Style>

Přidat Setter značky pro VisualStateManager.VisualStateGroups připojenou vlastnost s možností vazby:

<Style TargetType="Entry">
    <Setter Property="Margin" Value="20, 0" />
    <Setter Property="FontSize" Value="18" />
    <Setter Property="VisualStateManager.VisualStateGroups">

    </Setter>
</Style>

Vlastnost content pro Setter 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>

V rámci 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>

Zbytek značky VSM je stejný jako předtím.

Tady je VSM na stránce style , kde vidíte kompletní VSM značky:

<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>

Všechna Entry zobrazení na této stránce teď reagují na jejich vizuální stavy stejným způsobem. Všimněte si také, že "prioritní" stav teď obsahuje sekundu Setter , který poskytuje každé Entry z nich základní pozadí, pokud má vstupní fokus:

VSM ve stylu

Vizuální stavy v Xamarin.Forms

V následující tabulce jsou uvedeny vizuální stavy, které jsou definovány v Xamarin.Forms :

Třída Stavy Další informace
Button Pressed Vizuální stavy tlačítek
CheckBox IsChecked Vizuální stavy zaškrtávacího políčka
CarouselView DefaultItem, CurrentItem, PreviousItem, NextItem CarouselView vizuální stavy
ImageButton Pressed Obrázkové vizuální stavy
RadioButton Checked, Unchecked Vizuální stavy RadioButton
Switch On, Off Přepnout vizuální stavy
VisualElement Normal, Disabled, Focused, Selected Běžné stavy

Každý z těchto stavů je k dispozici prostřednictvím skupiny vizuálních stavů s názvem CommonStates .

Kromě toho CollectionView implementuje Selected stav. Další informace najdete v tématu Změna barvy vybrané položky.

Nastavit stav pro více elementů

V předchozích příkladech byly vizuální stavy připojené k jednotlivým prvkům 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é nastavily vlastnosti na jiných prvcích v rámci stejného oboru. Tím předejdete nutnosti opakování vizuálních stavů u každého prvku, na kterém jsou stavy provozovány.

SetterTyp má TargetName vlastnost typu string , která představuje cílový prvek, který se Setter bude zpracovávat pro vizuální stav. TargetNameJe-li definována vlastnost, Setter nastaví Property prvek elementu definovaného TargetName na Value :

<Setter TargetName="label"
        Property="Label.TextColor"
        Value="Red" />

V tomto příkladu Labellabel bude mít pojmenovaný TextColor vlastnost nastavenou na Red . Při nastavování TargetName vlastnosti musíte zadat úplnou cestu k vlastnosti v Property . Proto pro nastavení TextColor vlastnosti v Label , Property je zadána jako Label.TextColor .

Poznámka

Jakákoliv vlastnost, na kterou se odkazuje Setter objekt, musí být zálohovaná vlastností BIND.

Stránka VSM with setter cílový_název v ukázce VsmDemos ukazuje, jak nastavit stav pro více prvků z jedné skupiny vizuálních stavů. Soubor XAML se skládá z StackLayout obsahující Label element, Entry a 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>

Kód VSM je připojen k StackLayout . Existují dva vzájemně exkluzivní stavy s názvem "normální" a "stisknuté", přičemž každý stav obsahuje VisualState značky.

Stav "normální" je aktivní Button , když není stisknut, a odpověď na otázku lze zadat:

VSM setter cílový_název: normální stav

Stav "po stisknutí" bude aktivní při Button stisknutí klávesy:

VSM setter cílový_název: stisknutí State

VisualStatePři stisknutí tlačítka se určí, že se Button jeho Scale vlastnost změní z výchozí hodnoty 1 na 0,8. Kromě toho Entryentry bude mít vlastnost s názvem Text nastavenou hodnotu Paříž. Proto je výsledkem, že když Button je stisknuto, je zvětšeno, aby bylo mírně menší a Entry zobrazí se Paříž. Až Button se pak uvolní, změní se na výchozí hodnotu 1 a zobrazí se Entry všechny dříve zadané texty.

Důležité

Cesty vlastností nejsou aktuálně podporovány v Setter prvcích, které určují TargetName vlastnost.

Definování vlastních stavů vizuálů

Každá třída, která je odvozena z aplikace VisualElement , podporuje společné stavy "normální", "prioritní" a "zakázáno". Kromě toho CollectionView Třída podporuje stav "vybráno". Interně, Xamarin. Forms /BLOB/Master/ Xamarin.Forms . Core/VisualElement. cs "data-LINKTYPE =" External ">VisualElement Třída detekuje, kdy se stane povolená nebo zakázaná, nebo se zaměřuje na nefokus, a volá statickou Xamarin_Forms Xamarin.Forms _VisualStateManager_GoToState_ Xamarin_Forms _VisualElement_System_String_" data-LINKTYPE = "absolutní cesta" >VisualStateManager.GoToState metoda:

VisualStateManager.GoToState(this, "Focused");

Toto je jediný kód manažera vizuálního stavu, který najdete ve VisualElement třídě. Vzhledem k tomu, že GoToState je volána pro každý objekt založený na každé třídě, která je odvozena z VisualElement , můžete použít Správce vizuálního stavu s libovolným VisualElement objektem k reakci na tyto změny.

V zájmovém prostředí není název skupiny vizuálů "CommonStates" výslovně odkazován v VisualElement . Název skupiny není součástí rozhraní API pro manažera vizuálního stavu. V jednom ze dvou ukázkových programů, které jsou doposud zobrazené, můžete změnit název skupiny z "CommonStates" na cokoli jiného a program bude i nadále fungovat. Název skupiny je pouze obecný popis stavů v dané skupině. Implicitně se rozumí, že vizuální stavy v jakékoli skupině se vzájemně vylučují: jeden stav a jenom jeden stav je v každém okamžiku aktuální.

Pokud chcete implementovat vlastní vizuální stavy, budete muset volat VisualStateManager.GoToState z kódu. Nejčastěji se toto volání provede ze souboru kódu na pozadí vaší třídy stránky.

Stránka ověřování VSM v ukázce VsmDemos ukazuje, jak používat Správce vizuálního stavu v souvislosti s ověřováním vstupu. Soubor XAML se skládá z StackLayout obsahující dva Label prvky, Entry a a 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čky VSM jsou připojeny k StackLayout (pojmenovanému stackLayout ). Existují dva vzájemně se vylučující stavy s názvem "platné" a "neplatné", přičemž každý stav obsahuje VisualState značky.

Pokud neobsahuje Entry platné telefonní číslo, aktuální stav je "neplatné", takže Entry má na růžovém pozadí, druhý Label je viditelný a Button je zakázaný:

Ověření VSM: neplatné ověření stavu

Po zadání platného telefonního čísla se zobrazí aktuální stav "platnost". EntryZíská pozadí na vápno, druhá Label zmizí a Button teď je povolená:

Ověřování VSM: platný stav

Soubor kódu na pozadí zodpovídá za zpracování TextChanged události z Entry . Obslužná rutina používá regulární výraz k určení, zda je vstupní řetězec platný nebo nikoli. Metoda v souboru kódu na pozadí s názvem GoToState volá 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 být aktuálním stavem. Ale nikde v kódu je nějaký odkaz na název skupiny vizuálních stavů, i když je v jazyce XAML odkazováno jako "ValidationStates" pro účely srozumitelnosti.

Všimněte si, že soubor s kódem na pozadí musí brát pouze v úvahu objekt na stránce, která definuje vizuální stavy, a volat VisualStateManager.GoToState pro tento objekt. Důvodem je to, že vizuální stavy cílí na více objektů na stránce.

Můžete se setkat s tím, že pokud se soubor s kódem na pozadí musí odkazovat na objekt na stránce, která definuje vizuální stavy, proč nemůže soubor s kódem na pozadí jednoduše přistupovat k tomuto a jiným objektům přímo? Může to surely. Výhodou použití VSM je však, že můžete řídit, jak vizuální prvky reagují na jiný stav zcela v jazyce XAML, což udržuje všechny návrhy uživatelského rozhraní v jednom umístění. Tím se vyhnete nastavení vzhledu vizuálu přístupem k vizuálním prvkům přímo z kódu na pozadí.

Aktivační události vizuálního stavu

Vizuální stavy podporují aktivační procedury stavu, což jsou specializovaná skupina triggerů definujících podmínky, za kterých se VisualState má použít.

Aktivační události stavu jsou přidány do Xamarin_Forms _VisualState_StateTriggers "data-LINKTYPE =" absolutní cesta ">StateTriggers kolekce VisualState . Tato kolekce může obsahovat Trigger jednoho stavu nebo Trigger více stavů. A se VisualState použije, když jsou všechny triggery stavu v kolekci aktivní.

Při použití triggerů stavu k řízení vizuálních stavů pomocí Xamarin.Forms následujících pravidel přednosti určíte, která aktivační událost (a odpovídající VisualState ) bude aktivní:

  1. Libovolný Trigger, který je odvozen z StateTriggerBase .
  2. AdaptiveTriggerAktivuje se v důsledku AdaptiveTrigger splnění Xamarin_Forms _AdaptiveTrigger_MinWindowWidth data-LINKTYPE = "absolutní cesta" >MinWindowWidth podmínka.
  3. AdaptiveTriggerAktivuje se v důsledku AdaptiveTrigger splnění Xamarin_Forms _AdaptiveTrigger_MinWindowHeight data-LINKTYPE = "absolutní cesta" >MinWindowHeight podmínka.

Pokud je více triggerů současně aktivní (například dvě vlastní triggery), má přednost první aktivační událost, která je deklarována v označení.

Další informace o aktivačních událostech stavu naleznete v tématu triggery stavu.

Použití manažera vizuálního stavu pro adaptivní rozložení

Xamarin.FormsAplikaci běžící na telefonu je obvykle možné zobrazit v poměru stran na výšku nebo na šířku a Xamarin.Forms program běžící na ploše lze změnit tak, aby se předpokládalo mnoho různých velikostí a poměrů stran. Dobře navržená aplikace může zobrazit její obsah odlišně pro tyto různé faktory formuláře stránky nebo okna.

Tato technika se někdy označuje jako adaptivní rozložení. Vzhledem k tomu, že adaptivní rozložení zahrnuje pouze vizuály programu, je ideální aplikací Správce stavu.

Jednoduchým příkladem je aplikace, která zobrazuje malou kolekci tlačítek ovlivňujících obsah aplikace. V režimu na výšku se tato tlačítka můžou v horní části stránky zobrazovat v horizontálním řádku:

Adaptivní rozložení VSM: na výšku

V režimu na šířku je pole tlačítek možné přesunout na jednu stranu a zobrazí se ve sloupci:

Adaptivní rozložení VSM: na šířku

od shora dolů je program spuštěný na Univerzální platforma Windows, androidu a v iOS.

Stránka adaptivního rozložení VSM 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ánky nebo okna.)

VSM značky se vyskytují na čtyřech místech v souboru XAML. StackLayoutPojmenovaný mainStack obsahuje nabídku i obsah, což je Image element. StackLayoutMělo by se vytvořit svislá orientace v režimu na výšku a horizontální orientace 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é rozhraní StackLayoutmenuStack implementují nabídku tlačítek. Orientace tohoto rozložení je opakem mainStack . Nabídka by měla být vodorovná v režimu na výšku a svislá v režimu na šířku.

Čtvrtá část značky VSM je pro samotná tlačítka v implicitním stylu. Tyto sady značek VerticalOptions , HorizontalOptions a Margin vlastnosti specifické pro orientaci na výšku a na šířku.

Soubor kódu na pozadí nastaví BindingContext vlastnost menuStack pro implementaci Button příkazu a také připojí obslužnou rutinu k SizeChanged 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á SizeChanged rutina volá dva elementy a a potom prochází podřízené prvky pro volání VisualStateManager.GoToStateStackLayoutScrollViewmenuStackVisualStateManager.GoToStateButton prvků.

Může se zdát, že soubor kódu může zpracovávat změny orientace přímo nastavením vlastností prvků v souboru XAML, ale Správce vizuálních stavů je rozhodně strukturnější přístup. Všechny vizuály se uchovávají v souboru XAML, kde se snadněji prověří, udržují a upravuje.

Visual State Manager s Xamarin.University

Video 3.0 Visual State Manager