Bouton
L’interface utilisateur de l’application multiplateforme .NET (.NET MAUI) Button affiche du texte et répond à un appui ou à un clic qui ordonne à l’application d’effectuer une tâche. Un Button affiche généralement une chaîne de texte courte indiquant une commande, mais elle peut également afficher une image bitmap, ou une combinaison de texte et d’une image. Lorsque vous appuyez ou cliquez sur Button, ce dernier lance cette commande.
Button définit les propriétés suivantes :
BorderColor
, de type Color, décrit la couleur de bordure du bouton.BorderWidth
, de typedouble
, définit la largeur de la bordure du bouton.CharacterSpacing
, de typedouble
, définit l’espacement entre les caractères du texte du bouton.Command
, de type ICommand, définit la commande exécutée quand l’utilisateur appuie sur le bouton.CommandParameter
, de typeobject
, est le paramètre transmis àCommand
.ContentLayout
, de typeButtonContentLayout
, définit l’objet qui contrôle la position de l’image du bouton et l’espacement entre l’image et le texte du bouton.CornerRadius
, de typeint
, décrit le rayon d’angle de la bordure du bouton.FontAttributes
, de typeFontAttributes
, détermine le style du texte.FontAutoScalingEnabled
, de typebool
, définit si le texte du bouton reflète ou non les préférences de mise à l’échelle définies dans le système d’exploitation. La valeur par défaut de cette propriété esttrue
.FontFamily
, de typestring
, définit la famille de police.FontSize
, de typedouble
, définit la taille de police.- ImageSource, de type ImageSource, spécifie une image bitmap à afficher comme contenu du bouton.
LineBreakMode
, de typeLineBreakMode
, détermine comment le texte doit être traité lorsqu’il ne peut pas tenir sur une ligne.Padding
, de typeThickness
, détermine le remplissage du bouton.Text
, de typestring
, définit le texte affiché comme contenu du bouton.TextColor
, de type Color, décrit la couleur du texte du bouton.TextTransform
, de typeTextTransform
, définit la casse du texte du bouton.
Les propriétés s’appuient sur des objets BindableProperty, ce qui signifie qu’elles peuvent être les cibles de liaisons de données et mises en forme avec un style.
Remarque
Même si Button définit une ImageSource propriété, qui vous permet d’afficher une image sur le Button, cette propriété est destinée à être utilisée lors de l’affichage d’une petite icône en regard du Button texte.
En outre, Button définit des événements Clicked
, Pressed
et Released
. L’événement Clicked
est déclenché quand un appui sur Button avec un doigt ou un pointeur de souris est libéré de la surface du bouton. L’événement Pressed
est déclenché quand un doigt appuie sur un Button ou quand un bouton de souris est appuyé avec le pointeur positionné sur Button. L’événement Released
est déclenché quand le doigt ou le bouton de souris est libéré. En règle générale, un événement Clicked
est également déclenché en même temps que l’événement Released
, mais si le doigt ou le pointeur de souris s’éloigne de la surface du Button avant d’être libéré, il est possible que l’événement Clicked
ne se produise pas.
Important
La propriété d’un Button doit IsEnabled
être définie sur true
pour qu’il réponde aux appuis.
Créer un bouton
Pour créer un bouton, créez un objet Button et gérez son événement Clicked
.
L’exemple XAML suivant montre comment créer une Button :
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ButtonDemos.BasicButtonClickPage"
Title="Basic Button Click">
<StackLayout>
<Button Text="Click to Rotate Text!"
VerticalOptions="Center"
HorizontalOptions="Center"
Clicked="OnButtonClicked" />
<Label x:Name="label"
Text="Click the Button above"
FontSize="18"
VerticalOptions="Center"
HorizontalOptions="Center" />
</StackLayout>
</ContentPage>
La propriété Text
spécifie le texte qui apparaît dans l’élément Button. L’événement Clicked
est défini sur un gestionnaire d’événements nommé OnButtonClicked
. Ce gestionnaire d’événements se trouve dans le fichier code-behind :
public partial class BasicButtonClickPage : ContentPage
{
public BasicButtonClickPage ()
{
InitializeComponent ();
}
async void OnButtonClicked(object sender, EventArgs args)
{
await label.RelRotateTo(360, 1000);
}
}
Dans cet exemple, quand le Button est pressé, la méthode OnButtonClicked
s’exécute. L’argument sender
est l’objet Button responsable de cet événement. Vous pouvez l’utiliser pour accéder à l’objet Button ou pour faire la distinction entre plusieurs objets Button qui partagent le même événement Clicked
. Le gestionnaire Clicked
appelle une fonction d’animation qui fait pivoter le Label de 360 degrés en 1000 millisecondes :
Le code C# équivalent pour créer un Button est :
Button button = new Button
{
Text = "Click to Rotate Text!",
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Center
};
button.Clicked += async (sender, args) => await label.RelRotateTo(360, 1000);
Utiliser l’interface de commande
Une application peut répondre aux appuis de Button sans gérer l’événement Clicked
. Elle Button implémente un autre mécanisme de notification appelé interface de commande ou d’exécution de commandes. Cette opération comprend deux propriétés :
Command
de type ICommand, une interface définie dans l’espace de nomsSystem.Windows.Input
.- Une propriété
CommandParameter
de typeObject
.
Cette approche est particulièrement adaptée à la liaison de données, et en particulier lors de l’implémentation du modèle Model-View-ViewModel (MVVM). Dans une application MVVM, le viewmodel définit les propriétés de type ICommand qui sont ensuite connectées à des objets Button avec des liaisons de données. .NET MAUI définit également des classes Command
et Command<T>
qui implémentent l’interface ICommand et aident le viewmodel à définir des propriétés de type ICommand. Pour plus d’informations sur les commandes, consultez Commandes.
L’exemple suivant montre une classe viewmodel très simple qui définit une propriété de type double
nommée Number
, et deux propriétés de type ICommand nommées MultiplyBy2Command
et DivideBy2Command
:
public class CommandDemoViewModel : INotifyPropertyChanged
{
double number = 1;
public event PropertyChangedEventHandler PropertyChanged;
public ICommand MultiplyBy2Command { get; private set; }
public ICommand DivideBy2Command { get; private set; }
public CommandDemoViewModel()
{
MultiplyBy2Command = new Command(() => Number *= 2);
DivideBy2Command = new Command(() => Number /= 2);
}
public double Number
{
get
{
return number;
}
set
{
if (number != value)
{
number = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Number"));
}
}
}
}
Dans cet exemple, les deux propriétés ICommand sont initialisées dans le constructeur de la classe avec deux objets de type Command
. Les Command
constructeurs incluent une petite fonction (appelée argument du execute
constructeur) qui double ou réduit de moitié la valeur de la Number
propriété.
L’exemple XAML suivant consomme la classe CommandDemoViewModel
:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:ButtonDemos"
x:Class="ButtonDemos.BasicButtonCommandPage"
Title="Basic Button Command">
<ContentPage.BindingContext>
<local:CommandDemoViewModel />
</ContentPage.BindingContext>
<StackLayout>
<Label Text="{Binding Number, StringFormat='Value is now {0}'}"
FontSize="18"
VerticalOptions="Center"
HorizontalOptions="Center" />
<Button Text="Multiply by 2"
VerticalOptions="Center"
HorizontalOptions="Center"
Command="{Binding MultiplyBy2Command}" />
<Button Text="Divide by 2"
VerticalOptions="Center"
HorizontalOptions="Center"
Command="{Binding DivideBy2Command}" />
</StackLayout>
</ContentPage>
Dans cet exemple, l’élément Label et deux objets Button contiennent des liaisons aux trois propriétés de la classe CommandDemoViewModel
. À mesure que les deux objets Button sont appuyés, les commandes sont exécutées et le nombre change de valeur. L’avantage de cette approche par rapport aux gestionnaires Clicked
est que toute la logique impliquant la fonctionnalité de cette page se trouve dans le viewmodel plutôt que dans le fichier code-behind, ce qui permet de mieux séparer l’interface utilisateur de la logique métier.
Il est également possible que les objets Command
contrôlent l’activation et la désactivation des objets Button. Par exemple, supposons que vous souhaitiez limiter la plage de valeurs numériques comprises entre 210 et 2 à 10. Vous pouvez ajouter une autre fonction au constructeur (appelé l’argument canExecute
) qui retourne true
si le Button doit être activé :
public class CommandDemoViewModel : INotifyPropertyChanged
{
···
public CommandDemoViewModel()
{
MultiplyBy2Command = new Command(
execute: () =>
{
Number *= 2;
((Command)MultiplyBy2Command).ChangeCanExecute();
((Command)DivideBy2Command).ChangeCanExecute();
},
canExecute: () => Number < Math.Pow(2, 10));
DivideBy2Command = new Command(
execute: () =>
{
Number /= 2;
((Command)MultiplyBy2Command).ChangeCanExecute();
((Command)DivideBy2Command).ChangeCanExecute();
},
canExecute: () => Number > Math.Pow(2, -10));
}
···
}
Dans cet exemple, les appels à la méthode ChangeCanExecute
de Command
sont requis afin que la méthode Command
puisse appeler la méthode canExecute
et déterminer si le Button doit être désactivé ou non. Avec ce changement de code, à mesure que le nombre atteint la limite, le Button est désactivé.
Il est également possible que deux éléments Button ou plus soient liés à la même propriété ICommand. Les éléments Button peuvent être distingués à l’aide de la propriété CommandParameter
de Button. Dans ce cas, vous souhaiterez utiliser la classe Command<T>
générique. L’objet CommandParameter
est ensuite passé en tant qu’argument aux méthodes execute
et canExecute
. Pour plus d’informations, consultez Exécution de commandes.
Appuyez sur le bouton et relâchez
L’événement Pressed
est déclenché quand un doigt appuie sur un Button ou quand un bouton de souris est appuyé avec le pointeur positionné sur Button. L’événement Released
est déclenché quand le doigt ou le bouton de souris est libéré. En règle générale, un événement Clicked
est également déclenché en même temps que l’événement Released
, mais si le doigt ou le pointeur de souris s’éloigne de la surface du Button avant d’être libéré, il est possible que l’événement Clicked
ne se produise pas.
L’exemple XAML suivant montre un Label et un Button avec des gestionnaires attachés aux événements Pressed
et Released
:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ButtonDemos.PressAndReleaseButtonPage"
Title="Press and Release Button">
<StackLayout>
<Button Text="Press to Rotate Text!"
VerticalOptions="Center"
HorizontalOptions="Center"
Pressed="OnButtonPressed"
Released="OnButtonReleased" />
<Label x:Name="label"
Text="Press and hold the Button above"
FontSize="18"
VerticalOptions="Center"
HorizontalOptions="Center" />
</StackLayout>
</ContentPage>
Le fichier code-behind anime le Label lorsqu’un événement Pressed
se produit, mais suspend la rotation lorsqu’un événement Released
se produit :
public partial class PressAndReleaseButtonPage : ContentPage
{
IDispatcherTimer timer;
Stopwatch stopwatch = new Stopwatch();
public PressAndReleaseButtonPage()
{
InitializeComponent();
timer = Dispatcher.CreateTimer();
timer.Interval = TimeSpan.FromMilliseconds(16);
timer.Tick += (s, e) =>
{
label.Rotation = 360 * (stopwatch.Elapsed.TotalSeconds % 1);
};
}
void OnButtonPressed(object sender, EventArgs args)
{
stopwatch.Start();
timer.Start();
}
void OnButtonReleased(object sender, EventArgs args)
{
stopwatch.Stop();
timer.Stop();
}
}
Le résultat est que le Label pivote uniquement lorsqu’un doigt est en contact avec le Button, et s’arrête lorsque le doigt est relâché.
États visuels de Button
Button a un Pressed
VisualState qui peut être utilisé pour initier une modification visuelle au Button une fois appuyé, s’il est activé.
L’exemple de XAML suivant montre comment définir un état visuel pour l’état Pressed
:
<Button Text="Click me!"
...>
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="Scale"
Value="1" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Property="Scale"
Value="0.8" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver" />
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
</Button>
Dans cet exemple, l’état Pressed
VisualState spécifie que lorsque le Button est appuyé, sa propriété Scale
est modifiée en remplaçant la valeur par défaut de 1 par 0,8. L’élément Normal
VisualState spécifie que lorsque le Button est dans un état normal, sa propriété Scale
est définie sur 1. Par conséquent, l’effet global est que lorsque le Button est appuyé, il est remis à une échelle afin d’être légèrement plus petit, et quand le Button est libéré, il est remis à sa taille par défaut.
Important
Pour qu’un Button retourne à son état Normal
, le VisualStateGroup
doit également définir un état de PointerOver
. Si vous utilisez les styles du ResourceDictionary
créés par le modèle de projet d’application .NET MAUI, vous aurez déjà un style implicite de Button
qui définit l’état de PointerOver
.
Pour plus d’informations sur les états visuels, consultez États visuels.
Utiliser des bitmaps avec des boutons
La Button classe définit une propriété qui vous permet d’afficher ImageSource une petite image bitmap sur le , seul ou en combinaison avec du Buttontexte. Vous pouvez également spécifier la façon dont le texte et l’image sont organisés. La propriété ImageSource est de type ImageSource, ce qui signifie que les bitmaps peuvent être chargés à partir d’un fichier, d’une ressource intégrée, d’une URI ou d’un flux.
Les bitmaps ne sont pas mis à l’échelle pour s’adapter à un Button. La meilleure taille est généralement comprise entre 32 et 64 unités indépendantes de l’appareil, selon la taille à laquelle que vous souhaitez pour le bitmap.
Vous pouvez spécifier la façon dont les propriétés Text
et ImageSource sont organisées sur le Button à l’aide de la propriété ContentLayout
de Button. Cette propriété est de type ButtonContentLayout
, et son constructeur a deux arguments :
- Un membre de l’énumération
ImagePosition
:Left
,Top
, ouRight
Bottom
indiquant comment l’image bitmap apparaît par rapport au texte. - Une valeur
double
de l’espacement entre le bitmap et le texte.
En XAML, vous pouvez créer un Button et définir la propriété ContentLayout
en spécifiant uniquement le membre d’énumération, ou l’espacement, ou les deux dans n’importe quel ordre séparé par des virgules :
<Button Text="Button text"
ImageSource="button.png"
ContentLayout="Right, 20" />
Le code C# équivalent est :
Button button = new Button
{
Text = "Button text",
ImageSource = new FileImageSource
{
File = "button.png"
},
ContentLayout = new Button.ButtonContentLayout(Button.ButtonContentLayout.ImagePosition.Right, 20)
};
Remarque
Si un Button texte contient du texte et une image, il peut ne pas être possible d’ajuster tout le contenu à l’intérieur du bouton. Vous devez donc dimensionner votre image manuellement pour atteindre votre disposition souhaitée.
Désactiver un bouton
Une application entre parfois dans un état dans lequel un clic sur un Button n’est pas une opération valide. Dans ce cas, vous pouvez désactiver le Button en définissant sa propriété IsEnabled
sur false
.