Xamarin.Forms Gestionnaire d’état visuel
Utilisez le Gestionnaire d’état visuel 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 le Gestionnaire d’état visuel affecte les visuels de l’interface utilisateur.
VsM introduit le concept d’états visuels. Une Xamarin.Forms vue telle qu’une Button
vue 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.
Le Xamarin.Forms Gestionnaire d’état visuel définit un groupe d’états visuels nommé « CommonStates » avec les états visuels suivants :
- "Normal"
- « Désactivé »
- « Prioritaire »
- « Sélectionné »
Ce groupe d’états visuels est pris en charge pour toutes les classes qui dérivent VisualElement
de , 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 l’illustre cet article.
Remarque
Xamarin.Forms Les développeurs familiarisés avec les déclencheurs sont conscients 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 au déclenchement d’événements. Toutefois, l’utilisation de déclencheurs pour gérer différentes combinaisons de ces changements peut devenir assez déroutante. Historiquement, le Gestionnaire d’état visuel a été introduit dans les environnements XAML Windows pour atténuer la confusion résultant de combinaisons d’états visuels. Avec 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 courants
Le Gestionnaire d’état visuel vous permet d’inclure le balisage dans votre fichier XAML qui peut modifier l’apparence visuelle d’une vue si la vue est normale ou désactivée, ou qui a le focus d’entrée. Il s’agit des états courants.
Par exemple, supposez que vous disposez d’une vue Entry
sur votre page, et que vous souhaitez que l’apparence visuelle d’Entry
change des manières suivantes :
- L’
Entry
doit avoir un arrière-plan rose lorsque l’Entry
est désactivée. - L’
Entry
doit normalement avoir un arrière-plan vert-citron. - L’
Entry
doit être étendue à deux fois sa hauteur normale lorsqu’elle 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, séparez d’abord les Entry
balises de début et de fin :
<Entry FontSize="18">
</Entry>
Il est donné une taille de police explicite, car l’un des états utilise la FontSize
propriété pour doubler la taille du texte dans le 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 attachée définie par la VisualStateManager
classe. (Pour plus d’informations sur les propriétés pouvant être liées jointes, consultez l’article Propriétés jointes.) Il s’agit de la façon dont la VisualStateGroups
propriété est attachée à l’objet Entry
.
La propriété VisualStateGroups
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 l’un ou l’autre x:Name
des Name
deux dans le même élément.
La classe VisualStateGroup
définit une propriété nommée States
, qui est une collection d’objets VisualState
. States
est la propriété de contenu de VisualStateGroups
sorte que vous pouvez 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. Ceux-ci peuvent également être identifiés à l’aide 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 objets Setter
que ceux que vous utilisez dans un objet Style
.
Setters
n’est pas la propriété de contenu de , il est donc nécessaire d’inclure VisualState
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 d’étiquettes Setters
. Voici les objets qui définissent les Setter
é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 actif. Toute propriété référencée par un objet Setter
doit être secondée par une propriété pouvant être liée.
Le balisage similaire à celui-ci est la base de la page VSM en mode Affichage dans l’exemple de programme. La page inclut trois Entry
affichages, mais seul le deuxième a le balisage VSM attaché à celui-ci :
<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 une DataTrigger
partie de sa Trigger
collection. Cela entraîne la Entry
désactivation jusqu’à 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 est « Désactivé » de sorte que l’arrière-plan de la seconde Entry
est rose sur les écrans iOS et Android. L’implémentation UWP de Entry
ne permet pas de définir la couleur d’arrière-plan lorsque la valeur Entry
est désactivée.
Lorsque vous entrez du texte dans le troisième Entry
, le deuxième Entry
bascule dans l’état « Normal », et l’arrière-plan est désormais lime :
Lorsque vous touchez le deuxième Entry
, il obtient le focus d’entrée. Il bascule vers l’état « Prioritaire » et s’étend à deux fois sa hauteur :
Notez que l’arrière-plan Entry
ne conserve pas l’arrière-plan de lime lorsqu’il obtient le focus d’entrée. À mesure que le Gestionnaire d’état visuel bascule entre les états visuels, les propriétés définies par l’état précédent sont annulées. N’oubliez pas que les états visuels s’excluent mutuellement. L’état « Normal » ne signifie pas uniquement que l’option Entry
est activée. Cela signifie que l’option Entry
est activée et n’a pas de focus d’entrée.
Si vous souhaitez Entry
avoir un arrière-plan lime dans l’état « Prioritaire », 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 VisualStateGroup
doit contenir des VisualState
objets pour tous les états de ce groupe. S’il existe un état visuel qui n’a Setter
pas d’objets, 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 souhaiterez placer le balisage dans une Style
définition.
Voici l’élément implicite Style
existant pour les Entry
éléments de la page VSM En mode Affichage :
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
</Style>
Ajoutez des Setter
balises pour la VisualStateManager.VisualStateGroups
propriété pouvant être liée jointe :
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
</Setter>
</Style>
La propriété de contenu à Setter
utiliser 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 objets suivants VisualStateGroup
:
<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 que précédemment.
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>
À présent, toutes les Entry
vues de cette page répondent de la même façon à leurs états visuels. Notez également que l’état « Prioritaire » inclut désormais une seconde Setter
qui donne à chaque Entry
arrière-plan de 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 supplémentaires |
---|---|---|
Button |
Pressed |
États visuels de Button |
CheckBox |
IsChecked |
États visuels de CheckBox |
CarouselView |
DefaultItem , , CurrentItem PreviousItem , ,NextItem |
États visuels de CarouselView |
ImageButton |
Pressed |
États visuels d’ImageButton |
RadioButton |
Checked , Unchecked |
États visuels de RadioButton |
Switch |
On , Off |
États visuels de Switch |
VisualElement |
Normal , , Disabled Focused , ,Selected |
États courants |
Chacun de ces états est accessible via le groupe d’états visuels nommé CommonStates
.
En outre, l’état CollectionView
est implémenté Selected
. Pour plus d’informations, consultez Modifier la couleur d’élément sélectionnée.
Définir l’état sur plusieurs éléments
Dans les exemples précédents, les états visuels étaient attachés à, et opéraient sur, des éléments uniques. Toutefois, il est également possible de créer des états visuels attachés à un élément unique, mais qui définissent des propriétés sur d’autres éléments dans la même étendue. Cela évite de devoir répéter les é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 manipulera. Lorsque la TargetName
propriété est définie, la Setter
propriété définit l’élément Property
défini dans TargetName
:Value
<Setter TargetName="label"
Property="Label.TextColor"
Value="Red" />
Dans cet exemple, une Label
nommée label
aura sa propriété TextColor
définie sur Red
. Lorsque vous définissez la propriété TargetName
, vous devez spécifier le chemin d’accès complet à la propriété dans Property
. Par conséquent, pour définir la propriété TextColor
sur une Label
, Property
est spécifié comme Label.TextColor
.
Remarque
Toute propriété référencée par un objet Setter
doit être secondée par une propriété pouvant être liée.
La page VSM avec Setter TargetName dans l’exemple 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
élément, d’un Label
Entry
élément et d’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é au StackLayout
. Il existe deux états mutuellement exclusifs, nommés « Normal » et « Pressed », avec chaque état contenant des VisualState
balises.
L’état « Normal » est actif lorsque l’état Button
n’est pas appuyé et qu’une réponse à la question peut être entrée :
L’état « Appuyé » devient actif lorsque l’état Button
est appuyé :
L’argument « Pressed » VisualState
spécifie que lorsque la Button
propriété est enfoncée, sa Scale
propriété est remplacée par la valeur par défaut de 1 à 0,8. En outre, l’Entry
nommée entry
aura sa propriété Text
définie sur Paris. Par conséquent, le résultat est que lorsque la Button
pression est enfoncée, elle est rescaled pour être légèrement plus petite, et les Entry
affiches Paris. Ensuite, lorsque le Button
est relâché, il est remis à l’échelle à sa valeur par défaut de 1, et l’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
la prise en charge des états communs « Normal », « Prioritaire » et « Désactivé ». En outre, la CollectionView
classe prend en charge l’état « Sélectionné ». En interne, la VisualElement
classe détecte quand elle est activée ou désactivée, ou centrée ou non centré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é qu’il GoToState
est appelé pour chaque objet basé sur chaque classe qui dérive de VisualElement
, vous pouvez utiliser le Gestionnaire d’état visuel 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 affichés jusqu’à présent, vous pouvez remplacer le nom du groupe par « CommonStates » par tout autre élément, et le programme fonctionnera toujours. Le nom du groupe est simplement une description générale des états de ce groupe. Il est implicitement compris que les états visuels d’un groupe sont mutuellement exclusifs : 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 effectuerez cet appel à partir du fichier code-behind de votre classe de page.
La page Validation VSM de l’exemple montre comment utiliser visual State Manager en connexion 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 valides », avec chaque état contenant des VisualState
balises.
Si le Entry
numéro de téléphone n’est pas valide, l’état actuel est « Non valide », et le Entry
second est donc visible, le second Label
est visible et l’état Button
actuel est désactivé :
Lorsqu’un numéro de téléphone valide est entré, l’état actuel devient « Valide ». L’Entry
reçoit un arrière-plan vert-citron, la seconde Label
disparaît, et le Button
est désormais activé :
Le fichier code-behind est chargé de gérer l’événement TextChanged
à partir de l’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 du 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 n’existe aucune référence au nom du groupe d’états visuels, bien qu’elle soit référencée dans le code XAML comme « ValidationStates » à des fins de clarté.
Notez que le fichier code-behind doit uniquement tenir compte de l’objet sur la page qui définit les états visuels et d’appeler VisualStateManager.GoToState
cet objet. Cela est dû au fait que les deux états visuels ciblent plusieurs objets sur la page.
Vous pouvez vous demander : si le fichier code-behind doit référencer l’objet sur la page qui définit les états visuels, pourquoi le fichier code-behind ne peut-il pas simplement accéder directement à ce fichier et à d’autres objets ? C’est sûr. 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 en 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 directement aux éléments visuels à 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 collection StateTriggers
d’un VisualState
. Cette collection peut contenir un seul ou plusieurs déclencheurs d’état. Un VisualState
est appliqué lorsqu’un déclencheur d’état de la collection est actif.
Lorsque vous utilisez des déclencheurs d’état pour contrôler les états visuels, Xamarin.Forms utilise les règles de précédence suivantes pour déterminer quel déclencheur (et correspondant VisualState
) sera actif :
- Tout déclencheur dérivé de
StateTriggerBase
. - Un
AdaptiveTrigger
activé en raison de la satisfaction de la conditionMinWindowWidth
. - Un
AdaptiveTrigger
activé en raison de la satisfaction de la conditionMinWindowHeight
.
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 le Gestionnaire d’état visuel pour la disposition adaptative
Une Xamarin.Forms application s’exécutant sur un téléphone peut généralement être vue dans un rapport d’aspect 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é d’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 Mise en page adaptative VSM de l’exemple 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
nom 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
nom 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
, HorizontalOptions
et Margin
les propriétés spécifiques aux orientations portrait et paysage.
Le fichier code-behind définit la BindingContext
propriété de l’implémentation Button
de menuStack
commandes et attache é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
et ScrollView
les éléments, puis effectue une boucle dans les enfants de menuStack
l’appel VisualStateManager.GoToState
des Button
éléments.
Il peut sembler que si le fichier code-behind peut gérer les modifications d’orientation plus directement en définissant des propriétés d’é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 du Gestionnaire d’état visuel 3.0