Xamarin.Forms Visual State Manager
Użyj programu Visual State Manager, aby wprowadzić zmiany w elementach XAML na podstawie stanów wizualizacji ustawionych na podstawie kodu.
Program Visual State Manager (VSM) zapewnia ustrukturyzowany sposób wprowadzania zmian wizualnych w interfejsie użytkownika z kodu. W większości przypadków interfejs użytkownika aplikacji jest definiowany w języku XAML, a ten kod XAML zawiera znaczniki opisujące wpływ programu Visual State Manager na wizualizacje interfejsu użytkownika.
Program VSM wprowadza koncepcję stanów wizualizacji. Widok Xamarin.Forms taki jak Button
może mieć kilka różnych wyglądów wizualizacji w zależności od jego stanu bazowego — niezależnie od tego, czy jest wyłączony, czy naciśnięty, czy też ma fokus wejściowy. Są to stany przycisku.
Stany wizualizacji są zbierane w grupach stanu wizualizacji. Wszystkie stany wizualizacji w grupie stanu wizualizacji wykluczają się wzajemnie. Zarówno stany wizualizacji, jak i grupy stanów wizualnych są identyfikowane przez proste ciągi tekstowe.
Program Xamarin.Forms Visual State Manager definiuje jedną grupę stanu wizualizacji o nazwie "CommonStates" z następującymi stanami wizualnymi:
- "Normalny"
- "Wyłączone"
- "Ukierunkowane"
- "Wybrane"
Ta grupa stanów wizualizacji jest obsługiwana dla wszystkich klas, które pochodzą z VisualElement
klasy , która jest klasą bazową dla View
i Page
.
Możesz również zdefiniować własne grupy stanów wizualnych i stany wizualne, jak pokazano w tym artykule.
Uwaga
Xamarin.Forms deweloperzy zaznajomieni z wyzwalaczami wiedzą, że wyzwalacze mogą również wprowadzać zmiany w wizualizacjach w interfejsie użytkownika na podstawie zmian we właściwościach widoku lub wyzwalaniu zdarzeń. Jednak użycie wyzwalaczy do obsługi różnych kombinacji tych zmian może stać się dość mylące. Historycznie program Visual State Manager został wprowadzony w środowiskach opartych na języku XAML systemu Windows, aby złagodzić zamieszanie wynikające z kombinacji stanów wizualizacji. W przypadku programu VSM stany wizualizacji w grupie stanu wizualizacji zawsze wykluczają się wzajemnie. W dowolnym momencie tylko jeden stan w każdej grupie jest bieżącym stanem.
Wspólne stany
Program Visual State Manager umożliwia dołączenie znaczników do pliku XAML, który może zmienić wygląd wizualizacji widoku, jeśli widok jest normalny lub wyłączony lub ma fokus wejściowy. Są one znane jako wspólne stany.
Załóżmy na przykład, że masz Entry
widok na stronie i chcesz, aby wygląd wizualizacji Entry
zmienił się w następujący sposób:
- Element
Entry
powinien mieć różowe tło, gdyEntry
element jest wyłączony. - Powinno
Entry
mieć tło wapna normalnie. - Element
Entry
powinien rozwinąć się do dwukrotnie większej normalnej wysokości, gdy ma fokus wejściowy.
Możesz dołączyć znacznik VSM do pojedynczego widoku lub zdefiniować go w stylu, jeśli ma zastosowanie do wielu widoków. W dwóch następnych sekcjach opisano te podejścia.
Znaczniki programu VSM w widoku
Aby dołączyć znaczniki programu VSM do Entry
widoku, najpierw rozdziel tagi Entry
początkowe i końcowe:
<Entry FontSize="18">
</Entry>
Ma on jawny rozmiar czcionki, ponieważ jeden ze stanów użyje FontSize
właściwości , aby podwoić rozmiar tekstu w pliku Entry
.
Następnie wstaw VisualStateManager.VisualStateGroups
tagi między tymi tagami:
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
</VisualStateManager.VisualStateGroups>
</Entry>
VisualStateGroups
jest dołączoną właściwością powiązaną zdefiniowaną przez klasę VisualStateManager
. (Aby uzyskać więcej informacji na temat dołączonych właściwości możliwych do powiązania, zobacz artykuł Dołączone właściwości). W ten sposób VisualStateGroups
właściwość jest dołączona do Entry
obiektu.
Właściwość VisualStateGroups
jest typu VisualStateGroupList
, który jest kolekcją VisualStateGroup
obiektów. W tagach VisualStateManager.VisualStateGroups
wstaw parę tagów VisualStateGroup
dla każdej grupy stanów wizualizacji, które chcesz uwzględnić:
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Entry>
Zwróć uwagę, że VisualStateGroup
tag ma x:Name
atrybut wskazujący nazwę grupy. Klasa VisualStateGroup
definiuje Name
właściwość, której można użyć zamiast tego:
<VisualStateGroup Name="CommonStates">
Można użyć elementu x:Name
lub Name
, ale nie obu w tym samym elemecie.
Klasa VisualStateGroup
definiuje właściwość o nazwie States
, która jest kolekcją VisualState
obiektów. States
jest właściwością VisualStateGroups
zawartości , dzięki czemu można dołączyć VisualState
tagi bezpośrednio między tagamiVisualStateGroup
. (Właściwości zawartości zostały omówione w artykule Podstawowa składnia XAML).
Następnym krokiem jest dołączenie pary tagów dla każdego stanu wizualizacji w tej grupie. Można je również zidentyfikować przy użyciu polecenia x:Name
lub 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
definiuje właściwość o nazwie Setters
, która jest kolekcją Setter
obiektów. Są to te same Setter
obiekty, których używasz w Style
obiekcie.
Setters
nie jest właściwością VisualState
zawartości klasy , dlatego należy uwzględnić tagi elementów właściwości dla Setters
właściwości:
<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>
Teraz można wstawić jeden lub więcej Setter
obiektów między każdą parą tagów Setters
. Setter
Są to obiekty, które definiują opisane wcześniej stany wizualizacji:
<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żdy Setter
tag wskazuje wartość określonej właściwości, gdy ten stan jest bieżący. Każda właściwość, do którego Setter
odwołuje się obiekt, musi być wspierana przez właściwość, którą można powiązać.
Znaczniki podobne do tego są podstawą strony VSM w widoku w przykładowym programie. Strona zawiera trzy Entry
widoki, ale tylko drugi ma dołączony znacznik 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>
Zwróć uwagę, że drugi Entry
element jest DataTrigger
również częścią swojej Trigger
kolekcji. Spowoduje to wyłączenie elementu Entry
, dopóki coś nie zostanie wpisane do trzeciego Entry
elementu . Oto strona uruchamiania uruchomiona w systemach iOS, Android i platforma uniwersalna systemu Windows (UWP):
Bieżący stan wizualizacji to "Wyłączone", więc tło drugiego Entry
jest różowe na ekranach systemów iOS i Android. Implementacja platformy uniwersalnej systemu Entry
Windows nie zezwala na ustawianie koloru tła, gdy Entry
element jest wyłączony.
Gdy wprowadzisz jakiś tekst w trzecim Entry
, drugi Entry
przełączy się w stan "Normalny", a tło będzie teraz wapna:
Gdy dotkniesz drugiego Entry
elementu , zostanie wyświetlony fokus danych wejściowych. Przełącza się na stan "Skoncentrowany" i rozszerza się do dwukrotnie większej wysokości:
Zwróć uwagę, że Entry
tło wapna nie zachowuje się, gdy pobiera fokus danych wejściowych. Gdy program Visual State Manager przełącza się między stanami wizualizacji, właściwości ustawione przez poprzedni stan nie są ustawiane. Należy pamiętać, że stany wizualizacji wzajemnie się wykluczają. Stan "Normalny" nie oznacza wyłącznie, że Entry
jest włączony. Oznacza to, że Entry
parametr jest włączony i nie ma fokusu danych wejściowych.
Jeśli chcesz Entry
, aby tło wapna było w stanie "Skoncentrowane", dodaj kolejny Setter
element do tego stanu wizualizacji:
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
Aby te Setter
obiekty działały prawidłowo, VisualStateGroup
obiekt musi zawierać VisualState
obiekty dla wszystkich stanów w tej grupie. Jeśli istnieje stan wizualizacji, który nie ma żadnych Setter
obiektów, dołącz go mimo to jako pusty tag:
<VisualState x:Name="Normal" />
Znaczniki programu Visual State Manager w stylu
Często konieczne jest współużytkowanie tego samego znacznika programu Visual State Manager między co najmniej dwoma widokami. W takim przypadku należy umieścić znaczniki w Style
definicji.
Oto istniejąca niejawna Style
funkcja Entry
dla elementów na stronie Widok w programie VSM:
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
</Style>
Dodaj Setter
tagi dla dołączonej właściwości możliwej VisualStateManager.VisualStateGroups
do powiązania:
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
</Setter>
</Style>
Właściwość content dla Setter
parametru to Value
, więc wartość Value
właściwości można określić bezpośrednio w tych tagach. Ta właściwość jest typu VisualStateGroupList
:
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
</VisualStateGroupList>
</Setter>
</Style>
W tych tagach można uwzględnić jeden z większej VisualStateGroup
liczby obiektów:
<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>
Pozostała część znaczników VSM jest taka sama jak poprzednio.
Oto strona VSM w stylu przedstawiająca kompletny znacznik VSM:
<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>
Teraz wszystkie Entry
widoki na tej stronie odpowiadają w ten sam sposób na ich stany wizualizacji. Zwróć również uwagę, że stan "Ukierunkowane" zawiera teraz sekundę Setter
, która daje każde Entry
tło wapna również wtedy, gdy ma fokus wejściowy:
Stany wizualizacji w programie Xamarin.Forms
W poniższej tabeli wymieniono stany wizualizacji zdefiniowane w programie Xamarin.Forms:
Klasa | Stany | Więcej informacji |
---|---|---|
Button |
Pressed |
Stany wizualizacji przycisku |
CheckBox |
IsChecked |
Stany wizualizacji CheckBox |
CarouselView |
DefaultItem , , CurrentItem , , PreviousItem NextItem |
Stany wizualizacji CarouselView |
ImageButton |
Pressed |
Stany wizualizacji ImageButton |
RadioButton |
Checked , Unchecked |
Stany wizualizacji RadioButton |
Switch |
On , Off |
Przełączanie stanów wizualizacji |
VisualElement |
Normal , , Disabled , , Focused Selected |
Wspólne stany |
Dostęp do każdego z tych stanów można uzyskać za pośrednictwem grupy stanu wizualizacji o nazwie CommonStates
.
Ponadto element CollectionView
implementuje Selected
stan . Aby uzyskać więcej informacji, zobacz Zmienianie koloru zaznaczonego elementu.
Ustawianie stanu na wielu elementach
W poprzednich przykładach stany wizualne zostały dołączone do pojedynczych elementów i działały na nich. Istnieje jednak również możliwość utworzenia stanów wizualizacji dołączonych do jednego elementu, ale ustawiania właściwości na innych elementach w tym samym zakresie. Pozwala to uniknąć konieczności powtarzania stanów wizualnych na każdym elemencie, na którym działają stany.
Typ Setter
ma TargetName
właściwość typu string
, która reprezentuje element docelowy, Setter
który będzie manipulować stanem wizualizacji. Po zdefiniowaniu TargetName
Setter
właściwości ustawia Property
element zdefiniowany w TargetName
elemecie na Value
wartość :
<Setter TargetName="label"
Property="Label.TextColor"
Value="Red" />
W tym przykładzie Label
nazwa label
będzie miała właściwość TextColor
ustawioną na Red
. Podczas ustawiania TargetName
właściwości należy określić pełną ścieżkę do właściwości w pliku Property
. W związku z TextColor
tym, aby ustawić właściwość w Label
obiekcie , Property
jest określony jako Label.TextColor
.
Uwaga
Każda właściwość, do którego Setter
odwołuje się obiekt, musi być wspierana przez właściwość, którą można powiązać.
Na stronie Programu VSM ze stroną Setter TargetName w przykładzie pokazano, jak ustawić stan na wielu elementach z jednej grupy stanu wizualizacji. Plik XAML składa się z StackLayout
elementu zawierającego Label
element , Entry
i 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>
Znaczniki VSM są dołączone do elementu StackLayout
. Istnieją dwa wzajemnie wykluczające się stany o nazwach "Normal" i "Pressed" z każdym stanem zawierającym VisualState
tagi.
Stan "Normalny" jest aktywny, gdy Button
nie jest naciśnięty, a można wprowadzić odpowiedź na pytanie:
Stan "Naciśnięty" staje się aktywny po naciśnięciu Button
:
Wartość "Pressed" VisualState
określa, że po naciśnięciu Button
właściwość Scale
zostanie zmieniona z wartości domyślnej 1 na 0,8. Ponadto nazwana Entry
entry
będzie miała swoją Text
właściwość ustawioną na Paryż. W związku z tym wynik polega na tym, że po naciśnięciu Button
przycisku zostanie ona ponownie przeskalowana, aby była nieco mniejsza, a Entry
ekrany Paryż. Następnie, gdy Button
element zostanie wydany, zostanie ponownie przeskalowany do wartości domyślnej 1, a Entry
element wyświetla dowolny wcześniej wprowadzony tekst.
Ważne
Ścieżki właściwości nie są obecnie obsługiwane w Setter
elementach określających TargetName
właściwość.
Definiowanie własnych stanów wizualizacji
Każda klasa pochodząca z VisualElement
klasy obsługuje typowe stany "Normal", "Focused" i "Disabled". Ponadto CollectionView
klasa obsługuje stan "Selected". VisualElement
Wewnętrznie klasa wykrywa, kiedy staje się włączona lub wyłączona, albo skoncentrowana lub nieskoncentrowana, i wywołuje metodę statycznąVisualStateManager.GoToState
:
VisualStateManager.GoToState(this, "Focused");
Jest to jedyny kod programu Visual State Manager, który znajdziesz w VisualElement
klasie . Ponieważ GoToState
obiekt jest wywoływany dla każdego obiektu opartego na każdej klasie pochodzącej z VisualElement
klasy , można użyć programu Visual State Manager z dowolnym VisualElement
obiektem, aby reagować na te zmiany.
Co ciekawe, nazwa grupy stanu wizualizacji "CommonStates" nie jest jawnie przywoływana w pliku VisualElement
. Nazwa grupy nie jest częścią interfejsu API programu Visual State Manager. W jednym z dwóch przykładowych programów pokazanych do tej pory można zmienić nazwę grupy z "CommonStates" na cokolwiek innego, a program nadal będzie działać. Nazwa grupy jest jedynie ogólnym opisem stanów w tej grupie. Niejawnie rozumie się, że stany wizualizacji w każdej grupie wzajemnie się wykluczają: jeden stan i tylko jeden stan jest bieżący w dowolnym momencie.
Jeśli chcesz zaimplementować własne stany wizualizacji, musisz wywołać VisualStateManager.GoToState
kod. Najczęściej wykonasz to wywołanie z pliku za pomocą kodu klasy strony.
Na stronie Walidacja programu VSM w przykładzie pokazano, jak używać programu Visual State Manager w połączeniu z walidacją danych wejściowych. Plik XAML składa się z StackLayout
dwóch elementów: Entry
, i Button
Label
:
<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>
Znaczniki VSM są dołączone do elementu StackLayout
(o nazwie stackLayout
). Istnieją dwa wzajemnie wykluczające się stany o nazwie "Valid" i "Invalid" z każdym stanem zawierającym VisualState
tagi.
Jeśli parametr Entry
nie zawiera prawidłowego numeru telefonu, bieżący stan to "Nieprawidłowy", a więc Entry
ma różowe tło, drugi Label
jest widoczny, a Button
właściwość jest wyłączona:
Po wprowadzeniu prawidłowego numeru telefonu bieżący stan zmieni się na "Prawidłowy". Pobiera Entry
tło wapna, drugi Label
znika, a Button
element jest teraz włączony:
Plik związany z kodem jest odpowiedzialny za obsługę TextChanged
zdarzenia z pliku Entry
. Procedura obsługi używa wyrażenia regularnego, aby określić, czy ciąg wejściowy jest prawidłowy, czy nie. Metoda w pliku za pomocą kodu o nazwie GoToState
wywołuje metodę statyczną VisualStateManager.GoToState
dla stackLayout
metody :
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);
}
}
Zwróć również uwagę, że GoToState
metoda jest wywoływana z konstruktora w celu zainicjowania stanu. Zawsze powinien istnieć bieżący stan. Jednak nigdzie w kodzie nie ma żadnego odwołania do nazwy grupy stanu wizualizacji, chociaż jest on przywołyny w języku XAML jako "ValidationStates" na potrzeby jasności.
Zwróć uwagę, że plik związany z kodem musi uwzględniać tylko obiekt na stronie definiującej stany wizualizacji i wywołać VisualStateManager.GoToState
ten obiekt. Dzieje się tak, ponieważ oba stany wizualizacji są obiektami docelowymi wielu obiektów na stronie.
Możesz się zastanawiać: jeśli plik związany z kodem musi odwoływać się do obiektu na stronie definiującej stany wizualizacji, dlaczego nie można bezpośrednio uzyskać dostępu do tego pliku i innych obiektów? To z pewnością może. Jednak zaletą korzystania z programu VSM jest możliwość kontrolowania sposobu, w jaki elementy wizualne reagują na inny stan w całości w języku XAML, co zapewnia cały projekt interfejsu użytkownika w jednej lokalizacji. Pozwala to uniknąć ustawiania wyglądu wizualizacji przez uzyskiwanie dostępu do elementów wizualnych bezpośrednio z tyłu kodu.
Wyzwalacze stanu wizualizacji
Stany wizualne obsługują wyzwalacze stanu, które są wyspecjalizowaną grupą wyzwalaczy definiujących warunki, w których VisualState
należy zastosować.
Wyzwalacze stanu są dodawane do StateTriggers
kolekcji elementu VisualState
. Ta kolekcja może zawierać jeden wyzwalacz stanu lub wiele wyzwalaczy stanu. Element VisualState
zostanie zastosowany, gdy wszystkie wyzwalacze stanu w kolekcji są aktywne.
W przypadku używania wyzwalaczy stanu do kontrolowania stanów wizualizacji użyj następujących reguł pierwszeństwa, aby określić, Xamarin.Forms który wyzwalacz (i odpowiadający VisualState
im ) będzie aktywny:
- Każdy wyzwalacz pochodzący z elementu
StateTriggerBase
. - Aktywowano
AdaptiveTrigger
z powoduMinWindowWidth
spełnienia warunku. - Aktywowano
AdaptiveTrigger
z powoduMinWindowHeight
spełnienia warunku.
Jeśli wiele wyzwalaczy jest jednocześnie aktywnych (na przykład dwa wyzwalacze niestandardowe), pierwszy wyzwalacz zadeklarowany w znaczniku ma pierwszeństwo.
Aby uzyskać więcej informacji na temat wyzwalaczy stanu, zobacz Wyzwalacze stanu.
Używanie programu Visual State Manager do adaptacyjnego układu
Xamarin.Forms Aplikacja uruchomiona na telefonie może być zwykle widoczna w proporcjach pionowych lub poziomych, a Xamarin.Forms program uruchomiony na pulpicie może mieć rozmiar, aby założyć wiele różnych rozmiarów i współczynników proporcji. Dobrze zaprojektowana aplikacja może wyświetlać zawartość w inny sposób dla różnych czynników formularzy stron lub okien.
Ta technika jest czasami znana jako układ adaptacyjny. Ponieważ układ adaptacyjny obejmuje wyłącznie wizualizacje programu, jest to idealna aplikacja programu Visual State Manager.
Prostym przykładem jest aplikacja, która wyświetla niewielką kolekcję przycisków, które wpływają na zawartość aplikacji. W trybie pionowym te przyciski mogą być wyświetlane w poziomie wiersza w górnej części strony:
W trybie poziomym tablica przycisków może zostać przeniesiona na jedną stronę i wyświetlana w kolumnie:
Od góry do dołu program działa w platforma uniwersalna systemu Windows, Android i iOS.
Strona Układ adaptacyjny programu VSM w przykładzie definiuje grupę o nazwie "OrientationStates" z dwoma stanami wizualizacji o nazwach "Portret" i "Poziomo". (Bardziej złożone podejście może być oparte na kilku różnych szerokościach stron lub okien).
Znaczniki VSM występują w czterech miejscach w pliku XAML. Nazwana StackLayout
mainStack
zawiera zarówno menu, jak i zawartość, która jest elementem Image
. Powinno to StackLayout
mieć orientację pionową w trybie pionowym i orientację poziomą w trybie poziomym:
<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>
Wewnętrzna ScrollView
nazwana menuScroll
i StackLayout
nazwana menuStack
implementują menu przycisków. Orientacja tych układów jest przeciwieństwem mainStack
. Menu powinno być poziome w trybie pionowym i pionowym w trybie poziomym.
Czwarta sekcja znaczników VSM jest w niejawnym stylu dla samych przycisków. Ten znacznik ustawia VerticalOptions
właściwości , HorizontalOptions
i Margin
specyficzne dla orientacji pionowej i poziomej.
Plik związany z kodem ustawia BindingContext
właściwość menuStack
w celu zaimplementowania Button
poleceń, a także dołącza program obsługi do SizeChanged
zdarzenia strony:
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; }
}
Procedura SizeChanged
obsługi wywołuje VisualStateManager.GoToState
dwa StackLayout
elementy i ScrollView
, a następnie przechodzi przez elementy podrzędne menuStack
elementu w celu wywołania VisualStateManager.GoToState
Button
elementów.
Może się wydawać, że plik za kodem może obsługiwać zmiany orientacji bardziej bezpośrednio, ustawiając właściwości elementów w pliku XAML, ale program Visual State Manager jest zdecydowanie bardziej ustrukturyzowanym podejściem. Wszystkie wizualizacje są przechowywane w pliku XAML, gdzie stają się łatwiejsze do sprawdzania, konserwacji i modyfikowania.
Visual State Manager z platformą Xamarin.University
Xamarin.Forms 3.0 Visual State Manager wideo