Xamarin.Forms Gestionnaire d’état visuel
Utilisez visual State Manager pour apporter des modifications aux éléments XAML en fonction des états visuels définis à partir du code.
Visual State Manager (VSM) fournit un moyen structuré d’apporter des modifications visuelles à l’interface utilisateur à partir du code. Dans la plupart des cas, l’interface utilisateur de l’application est définie en XAML, et ce CODE XAML inclut le balisage décrivant comment visual State Manager affecte les visuels de l’interface utilisateur.
Le VSM introduit le concept d’états visuels. Une Xamarin.Forms vue telle qu’un Button
peut avoir plusieurs apparences visuelles différentes en fonction de son état sous-jacent , qu’elle soit désactivée ou enfoncée, ou qu’elle ait le focus d’entrée. Il s’agit des états du bouton.
Les états visuels sont collectés dans des groupes d’états visuels. Tous les états visuels d’un groupe d’états visuels s’excluent mutuellement. Les états visuels et les groupes d’états visuels sont identifiés par des chaînes de texte simples.
Visual Xamarin.Forms State Manager définit un groupe d’états visuels nommé « CommonStates » avec les états visuels suivants :
- "Normal"
- « Désactivé »
- « Focus »
- « Sélectionné »
Ce groupe d’états visuels est pris en charge pour toutes les classes qui dérivent de VisualElement
, qui est la classe de base pour View
et Page
.
Vous pouvez également définir vos propres groupes d’états visuels et états visuels, comme le montre cet article.
Notes
Xamarin.Forms les développeurs familiarisés avec les déclencheurs savent que les déclencheurs peuvent également apporter des modifications aux visuels dans l’interface utilisateur en fonction des modifications apportées aux propriétés d’une vue ou du déclenchement d’événements. Toutefois, l’utilisation de déclencheurs pour traiter diverses combinaisons de ces modifications peut devenir assez déroutante. Historiquement, visual State Manager a été introduit dans les environnements XAML Windows pour atténuer la confusion résultant des combinaisons d’états visuels. Avec le VSM, les états visuels au sein d’un groupe d’états visuels sont toujours mutuellement exclusifs. À tout moment, un seul état dans chaque groupe est l’état actuel.
États communs
Visual State Manager vous permet d’inclure un balisage dans votre fichier XAML qui peut modifier l’apparence visuelle d’une vue si la vue est normale ou désactivée, ou si le focus d’entrée est activé. Ces états sont appelés états communs.
Par exemple, supposons que vous ayez une Entry
vue sur votre page et que vous souhaitiez que l’apparence visuelle du Entry
change de la manière suivante :
- doit
Entry
avoir un arrière-plan rose lorsque leEntry
est désactivé. - Le
Entry
doit avoir un fond de chaux normalement. - Le
Entry
doit atteindre deux fois sa hauteur normale lorsqu’il a le focus d’entrée.
Vous pouvez attacher le balisage VSM à une vue individuelle ou vous pouvez le définir dans un style s’il s’applique à plusieurs vues. Les deux sections suivantes décrivent ces approches.
Balisage VSM sur une vue
Pour attacher le balisage VSM à une Entry
vue, commencez par séparer le Entry
en balises de début et de fin :
<Entry FontSize="18">
</Entry>
Il reçoit une taille de police explicite, car l’un des états utilise la FontSize
propriété pour doubler la taille du texte dans .Entry
Ensuite, insérez VisualStateManager.VisualStateGroups
des balises entre ces balises :
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
</VisualStateManager.VisualStateGroups>
</Entry>
VisualStateGroups
est une propriété pouvant être liée définie par la VisualStateManager
classe . (Pour plus d’informations sur les propriétés liées attachées, consultez l’article Propriétés jointes.) C’est ainsi que la VisualStateGroups
propriété est attachée à l’objet Entry
.
La VisualStateGroups
propriété est de type VisualStateGroupList
, qui est une collection d’objets VisualStateGroup
. Dans les VisualStateManager.VisualStateGroups
balises, insérez une paire de VisualStateGroup
balises pour chaque groupe d’états visuels que vous souhaitez inclure :
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Entry>
Notez que la VisualStateGroup
balise a un x:Name
attribut indiquant le nom du groupe. La VisualStateGroup
classe définit une Name
propriété que vous pouvez utiliser à la place :
<VisualStateGroup Name="CommonStates">
Vous pouvez utiliser x:Name
ou mais Name
pas les deux dans le même élément.
La VisualStateGroup
classe définit une propriété nommée States
, qui est une collection d’objets VisualState
. States
est la propriété content de VisualStateGroups
afin que vous puissiez inclure les VisualState
balises directement entre les VisualStateGroup
balises. (Les propriétés de contenu sont abordées dans l’article Syntaxe XAML essentielle.)
L’étape suivante consiste à inclure une paire d’étiquettes pour chaque état visuel de ce groupe. Vous pouvez également les identifier à l’aide de x:Name
ou 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
définit une propriété nommée Setters
, qui est une collection d’objets Setter
. Il s’agit des mêmes Setter
objets que ceux que vous utilisez dans un Style
objet.
Setters
n’est pas la propriété de contenu de VisualState
, il est donc nécessaire d’inclure des balises d’élément de propriété pour la Setters
propriété :
<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>
Vous pouvez maintenant insérer un ou plusieurs Setter
objets entre chaque paire de Setters
balises. Voici les Setter
objets qui définissent les états visuels décrits précédemment :
<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>
Chaque Setter
balise indique la valeur d’une propriété particulière lorsque cet état est actuel. Toute propriété référencée par un Setter
objet doit être soutenue par une propriété pouvant être liée.
Le balisage similaire à celui-ci est la base de la page VSM on View dans l’exemple de programme VsmDemos . La page comprend trois Entry
affichages, mais seule la deuxième est associée au balisage 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>
Notez que le second Entry
a également un DataTrigger
dans sa Trigger
collection. Cela entraîne la désactivation de jusqu’à Entry
ce que quelque chose soit tapé dans le troisième Entry
. Voici la page au démarrage s’exécutant sur iOS, Android et le plateforme Windows universelle (UWP) :
L’état visuel actuel étant « Désactivé », l’arrière-plan du second Entry
est rose sur les écrans iOS et Android. L’implémentation UWP de ne permet pas de Entry
définir la couleur d’arrière-plan lorsque le Entry
est désactivé.
Lorsque vous entrez du texte dans le troisième Entry
, le second Entry
passe à l’état « Normal » et l’arrière-plan est maintenant lime :
Lorsque vous appuyez sur le deuxième Entry
, il obtient le focus d’entrée. Il passe à l’état « Focus » et s’étend à deux fois sa hauteur :
Notez que le Entry
ne conserve pas l’arrière-plan lime lorsqu’il obtient le focus d’entrée. Lorsque le Gestionnaire d’état visuel bascule entre les états visuels, les propriétés définies par l’état précédent ne sont pas définies. N’oubliez pas que les états visuels s’excluent mutuellement. L’état « Normal » ne signifie pas uniquement que le Entry
est activé. Cela signifie que le est activé et n’a pas de Entry
focus d’entrée.
Si vous souhaitez que le Entry
ait un arrière-plan lime à l’état « Focus », ajoutez-en un autre Setter
à cet état visuel :
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
Pour que ces Setter
objets fonctionnent correctement, un doit contenir des VisualStateGroup
VisualState
objets pour tous les états de ce groupe. S’il existe un état visuel qui n’a aucun Setter
objet, incluez-le quand même comme une balise vide :
<VisualState x:Name="Normal" />
Balisage visual State Manager dans un style
Il est souvent nécessaire de partager le même balisage Visual State Manager entre deux vues ou plus. Dans ce cas, vous devez placer le balisage dans une Style
définition.
Voici l’implicite Style
existant pour les éléments de la Entry
page VSM à l’affichage :
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
</Style>
Ajoutez Setter
des balises pour la VisualStateManager.VisualStateGroups
propriété pouvant être liée :
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
</Setter>
</Style>
La propriété content pour Setter
est Value
, de sorte que la valeur de la Value
propriété peut être spécifiée directement dans ces balises. Cette propriété est de type VisualStateGroupList
:
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
</VisualStateGroupList>
</Setter>
</Style>
Dans ces balises, vous pouvez inclure l’un des autres VisualStateGroup
objets :
<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>
Le reste du balisage VSM est le même qu’auparavant.
Voici la page VSM dans Style montrant le balisage VSM complet :
<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>
Désormais, toutes les Entry
vues de cette page répondent de la même façon à leurs états visuels. Notez également que l’état « Focus » inclut désormais une seconde Setter
qui donne à chacun Entry
un arrière-plan lime également lorsqu’il a le focus d’entrée :
États visuels dans Xamarin.Forms
Le tableau suivant répertorie les états visuels définis dans Xamarin.Forms:
Classe | États | Informations complémentaires |
---|---|---|
Button |
Pressed |
États visuels du bouton |
CheckBox |
IsChecked |
États visuels CheckBox |
CarouselView |
DefaultItem , CurrentItem , PreviousItem , NextItem |
États visuels CarouselView |
ImageButton |
Pressed |
États visuels ImageButton |
RadioButton |
Checked , Unchecked |
États visuels RadioButton |
Switch |
On , Off |
Changer d’état visuel |
VisualElement |
Normal , Disabled , Focused , Selected |
États communs |
Chacun de ces états est accessible via le groupe d’états visuels nommé CommonStates
.
En outre, implémente CollectionView
l’état Selected
. Pour plus d’informations, consultez Modifier la couleur de l’élément sélectionné.
Définir l’état sur plusieurs éléments
Dans les exemples précédents, les états visuels ont été attachés à des éléments uniques et ont été utilisés sur eux. Toutefois, il est également possible de créer des états visuels qui sont attachés à un seul élément, mais qui définissent des propriétés sur d’autres éléments dans la même étendue. Cela évite d’avoir à répéter des états visuels sur chaque élément sur lequel les états opèrent.
Le Setter
type a une TargetName
propriété, de type string
, qui représente l’élément cible que le Setter
pour un état visuel va manipuler. Lorsque la TargetName
propriété est définie, le Setter
définit de l’élément Property
défini dans sur Value
TargetName
:
<Setter TargetName="label"
Property="Label.TextColor"
Value="Red" />
Dans cet exemple, une Label
propriété nommée label
a TextColor
la Red
valeur . Lorsque vous définissez la TargetName
propriété, vous devez spécifier le chemin d’accès complet à la propriété dans Property
. Par conséquent, pour définir la TextColor
propriété sur un Label
, Property
est spécifié en tant que Label.TextColor
.
Notes
Toute propriété référencée par un Setter
objet doit être soutenue par une propriété pouvant être liée.
La page VSM avec Setter TargetName dans l’exemple VsmDemos montre comment définir l’état sur plusieurs éléments, à partir d’un seul groupe d’états visuels. Le fichier XAML se compose d’un StackLayout
contenant un Label
élément, un Entry
et un 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>
Le balisage VSM est attaché à .StackLayout
Il existe deux états mutuellement exclusifs, nommés « Normal » et « Pressed », chaque état contenant des VisualState
balises.
L’état « Normal » est actif lorsque le Button
n’est pas enfoncé, et une réponse à la question peut être entrée :
L’état « Pressed » devient actif lorsque le Button
est enfoncé :
L’option « Pressed » VisualState
spécifie que lorsque la Button
est enfoncée, sa Scale
propriété passe de la valeur par défaut de 1 à 0,8. En outre, le Entry
nommé entry
aura sa Text
propriété définie sur Paris. Par conséquent, le résultat est que lorsque le Button
est enfoncé, il est redimensionné pour être légèrement plus petit, et les Entry
affiches Paris. Ensuite, lorsque le Button
est libéré, il est redimensionné à sa valeur par défaut de 1, et le Entry
affiche tout texte précédemment entré.
Important
Les chemins de propriété ne sont actuellement pas pris en charge dans Setter
les éléments qui spécifient la TargetName
propriété.
Définir vos propres états visuels
Chaque classe dérivée de VisualElement
prend en charge les états communs « Normal », « Focus » et « Disabled ». En outre, la CollectionView
classe prend en charge l’état « Sélectionné ». En interne, la VisualElement
classe détecte quand elle devient activée ou désactivée, ou concentrée ou non ciblée, et appelle la méthode statique VisualStateManager.GoToState
:
VisualStateManager.GoToState(this, "Focused");
Il s’agit du seul code Visual State Manager que vous trouverez dans la VisualElement
classe . Étant donné que GoToState
est appelé pour chaque objet en fonction de chaque classe qui dérive de VisualElement
, vous pouvez utiliser visual State Manager avec n’importe quel VisualElement
objet pour répondre à ces modifications.
Il est intéressant de noter que le nom du groupe d’états visuels « CommonStates » n’est pas explicitement référencé dans VisualElement
. Le nom du groupe ne fait pas partie de l’API du Gestionnaire d’état visuel. Dans l’un des deux exemples de programme présentés jusqu’à présent, vous pouvez remplacer le nom du groupe « CommonStates » par autre chose, et le programme fonctionnera toujours. Le nom du groupe est simplement une description générale des états de ce groupe. Il est implicitement entendu que les états visuels d’un groupe s’excluent mutuellement : un état et un seul état est actif à tout moment.
Si vous souhaitez implémenter vos propres états visuels, vous devez appeler VisualStateManager.GoToState
à partir du code. Le plus souvent, vous effectuez cet appel à partir du fichier code-behind de votre classe de page.
La page Validation VSM de l’exemple VsmDemos montre comment utiliser Visual State Manager en lien avec la validation d’entrée. Le fichier XAML se compose d’un StackLayout
contenant deux Label
éléments, un Entry
et un 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>
Le balisage VSM est attaché au StackLayout
(nommé stackLayout
). Il existe deux états mutuellement exclusifs, nommés « Valide » et « Non valide », chaque état contenant des VisualState
balises.
Si le Entry
ne contient pas de numéro de téléphone valide, l’état actuel est « Non valide », de sorte que le Entry
a un arrière-plan rose, le second Label
est visible et le Button
est désactivé :
Lorsqu’un numéro de téléphone valide est entré, l’état actuel devient « Valide ». le Entry
obtient un arrière-plan lime, le second Label
disparaît et le Button
est maintenant activé :
Le fichier code-behind est responsable de la gestion de l’événement TextChanged
à partir de .Entry
Le gestionnaire utilise une expression régulière pour déterminer si la chaîne d’entrée est valide ou non. La méthode dans le fichier code-behind nommé GoToState
appelle la méthode statique VisualStateManager.GoToState
pour 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);
}
}
Notez également que la GoToState
méthode est appelée à partir du constructeur pour initialiser l’état. Il doit toujours y avoir un état actuel. Mais nulle part dans le code il n’y a aucune référence au nom du groupe d’états visuels, bien qu’il soit référencé dans le XAML comme « ValidationStates » à des fins de clarté.
Notez que le fichier code-behind doit uniquement tenir compte de l’objet dans la page qui définit les états visuels et appeler VisualStateManager.GoToState
pour cet objet. Cela est dû au fait que les deux états visuels ciblent plusieurs objets sur la page.
Vous vous demandez peut-être : si le fichier code-behind doit référencer l’objet dans la page qui définit les états visuels, pourquoi le fichier code-behind ne peut-il pas simplement accéder directement à cet objet et à d’autres objets ? C’est sûrement possible. Toutefois, l’avantage de l’utilisation de VSM est que vous pouvez contrôler la façon dont les éléments visuels réagissent à un état différent entièrement dans XAML, ce qui conserve toute la conception de l’interface utilisateur dans un seul emplacement. Cela évite de définir l’apparence visuelle en accédant aux éléments visuels directement à partir du code-behind.
Déclencheurs d’état visuel
Les états visuels prennent en charge les déclencheurs d’état, qui sont un groupe spécialisé de déclencheurs qui définissent les conditions dans lesquelles un VisualState
doit être appliqué.
Les déclencheurs d’état sont ajoutés à la StateTriggers
collection d’un VisualState
. Cette collection peut contenir un déclencheur d’état unique ou plusieurs déclencheurs d’état. Un VisualState
est appliqué lorsque tous les déclencheurs d’état de la collection sont actifs.
Lorsque vous utilisez des déclencheurs d’état pour contrôler les états visuels, Xamarin.Forms utilisez les règles de priorité suivantes pour déterminer quel déclencheur (et correspondant VisualState
) sera actif :
- Tout déclencheur qui dérive de
StateTriggerBase
. - activé
AdaptiveTrigger
en raison de laMinWindowWidth
condition remplie. - activé
AdaptiveTrigger
en raison de laMinWindowHeight
condition remplie.
Si plusieurs déclencheurs sont actifs simultanément (par exemple, deux déclencheurs personnalisés), le premier déclencheur déclaré dans le balisage est prioritaire.
Pour plus d’informations sur les déclencheurs d’état, consultez Déclencheurs d’état.
Utiliser visual State Manager pour la disposition adaptative
Une Xamarin.Forms application s’exécutant sur un téléphone peut généralement être visualisée dans un format portrait ou paysage, et un Xamarin.Forms programme s’exécutant sur le bureau peut être redimensionné pour supposer de nombreuses tailles et proportions différentes. Une application bien conçue peut afficher son contenu différemment pour ces différents facteurs de forme de page ou de fenêtre.
Cette technique est parfois appelée disposition adaptative. Étant donné que la disposition adaptative implique uniquement les visuels d’un programme, il s’agit d’une application idéale du Gestionnaire d’état visuel.
Un exemple simple est une application qui affiche une petite collection de boutons qui affectent le contenu de l’application. En mode portrait, ces boutons peuvent être affichés dans une ligne horizontale en haut de la page :
En mode paysage, le tableau de boutons peut être déplacé sur un côté et affiché dans une colonne :
De haut en bas, le programme s’exécute sur les plateforme Windows universelle, Android et iOS.
La page Disposition adaptative VSM de l’exemple VsmDemos définit un groupe nommé « OrientationStates » avec deux états visuels nommés « Portrait » et « Paysage ». (Une approche plus complexe peut être basée sur plusieurs largeurs de page ou de fenêtre différentes.)
Le balisage VSM se produit à quatre emplacements dans le fichier XAML. Le StackLayout
nommé mainStack
contient à la fois le menu et le contenu, qui est un Image
élément. Cela StackLayout
doit avoir une orientation verticale en mode portrait et une orientation horizontale en mode paysage :
<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>
Le nom menuScroll
interne ScrollView
et le StackLayout
nommé menuStack
implémentent le menu des boutons. L’orientation de ces dispositions est opposée à mainStack
. Le menu doit être horizontal en mode portrait et vertical en mode paysage.
La quatrième section du balisage VSM est dans un style implicite pour les boutons eux-mêmes. Ce balisage définit VerticalOptions
les propriétés , HorizontalOptions
et Margin
spécifiques aux orientations portrait et paysage.
Le fichier code-behind définit la BindingContext
propriété de menuStack
pour implémenter Button
la commande et joint également un gestionnaire à l’événement SizeChanged
de la page :
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; }
}
Le SizeChanged
gestionnaire appelle VisualStateManager.GoToState
les deux StackLayout
éléments et , ScrollView
puis effectue une boucle à travers les enfants de menuStack
pour appeler VisualStateManager.GoToState
pour les Button
éléments.
Il peut sembler que le fichier code-behind peut gérer les changements d’orientation plus directement en définissant les propriétés des éléments dans le fichier XAML, mais visual State Manager est certainement une approche plus structurée. Tous les visuels sont conservés dans le fichier XAML, où ils deviennent plus faciles à examiner, à gérer et à modifier.
Visual State Manager avec Xamarin.University
Xamarin.Forms Vidéo 3.0 Visual State Manager