Xamarin.Forms Slider

Download Sample Télécharger l’exemple

Utilisez un curseur pour sélectionner une plage de valeurs continues.

Il Xamarin.FormsSlider s’agit d’une barre horizontale qui peut être manipulée par l’utilisateur pour sélectionner une double valeur dans une plage continue.

Définit Slider trois propriétés de type double:

  • Minimum est le minimum de la plage, avec une valeur par défaut de 0.
  • Maximum est le maximum de la plage, avec une valeur par défaut de 1.
  • Value est la valeur du curseur, qui peut être comprise entre Minimum et Maximum a une valeur par défaut de 0.

Les trois propriétés sont sauvegardées par BindableProperty des objets. La Value propriété a un mode de liaison par défaut , ce qui signifie qu’elle convient en tant que source de BindingMode.TwoWayliaison dans une application qui utilise l’architecture MVVM (Model-View-ViewModel).

Avertissement

En interne, les Slider garanties sont Minimum inférieures à Maximum. Si Minimum ou Maximum n’est jamais Maximumdéfini de sorte qu’il Minimum ne soit pas inférieur à , une exception est levée. Pour plus d’informations sur la définition des propriétés et des Minimum propriétés, consultez la section Précautions ci-dessous.Maximum

Le Slider cocédent la Value propriété afin qu’elle soit comprise Minimum entre et Maximuminclus. Si la Minimum propriété est définie sur une valeur supérieure à la Value propriété, la SliderValue propriété Minimumest définie sur . De même, si Maximum elle est définie sur une valeur inférieure Valueà , Slider définit la propriété Maximumsur Value .

Slider définit un ValueChanged événement déclenché lorsque les Value modifications sont effectuées, soit par le biais de la manipulation de l’utilisateur Slider , soit lorsque le programme définit la Value propriété directement. Un ValueChanged événement est également déclenché lorsque la Value propriété est cochée comme décrit dans le paragraphe précédent.

L’objet ValueChangedEventArgs qui accompagne l’événement ValueChanged a deux propriétés, à la fois de type double: OldValue et NewValue. Au moment où l’événement est déclenché, la valeur est NewValue identique à la Value propriété de l’objet Slider .

Slider définit DragStarted également et DragCompleted événements, qui sont déclenchés au début et à la fin de l’action de glisser. Contrairement à l’événement ValueChanged , les DragStarted événements ne DragCompleted sont déclenchés qu’à l’aide de la manipulation de l’utilisateur Slider. Lorsque l’événement DragStarted se déclenche, le DragStartedCommandtype , ICommandest exécuté. De même, lorsque l’événement DragCompleted se déclenche, le DragCompletedCommand, de type ICommand, est exécuté.

Avertissement

N’utilisez pas d’options de disposition horizontale non contraintes de Center, Startou End avec Slider. Sur Android et UWP, la Slider barre est réduite à une barre de longueur nulle et sur iOS, la barre est très courte. Conservez le paramètre par défaut HorizontalOptions et n’utilisez pas une largeur de données lors de FillAuto la mise Slider en Grid page.

Il Slider définit également plusieurs propriétés qui affectent son apparence :

Remarque

Les ThumbColor propriétés et ThumbImageSource les propriétés s’excluent mutuellement. Si les deux propriétés sont définies, la ThumbImageSource propriété est prioritaire.

Code de curseur de base et balisage

L’exemple SliderDemos commence par trois pages qui sont fonctionnellement identiques, mais qui sont implémentées de différentes manières. La première page utilise uniquement du code C#, la deuxième utilise XAML avec un gestionnaire d’événements dans le code, et la troisième est en mesure d’éviter le gestionnaire d’événements à l’aide de la liaison de données dans le fichier XAML.

Création d’un curseur dans le code

La page Code du curseur de base dans l’exemple SliderDemos montre comment créer un Slider et deux Label objets dans le code :

public class BasicSliderCodePage : ContentPage
{
    public BasicSliderCodePage()
    {
        Label rotationLabel = new Label
        {
            Text = "ROTATING TEXT",
            FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.CenterAndExpand
        };

        Label displayLabel = new Label
        {
            Text = "(uninitialized)",
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.CenterAndExpand
        };

        Slider slider = new Slider
        {
            Maximum = 360
        };
        slider.ValueChanged += (sender, args) =>
        {
            rotationLabel.Rotation = slider.Value;
            displayLabel.Text = String.Format("The Slider value is {0}", args.NewValue);
        };

        Title = "Basic Slider Code";
        Padding = new Thickness(10, 0);
        Content = new StackLayout
        {
            Children =
            {
                rotationLabel,
                slider,
                displayLabel
            }
        };
    }
}

Il Slider est initialisé pour avoir une Maximum propriété de 360. Le ValueChanged gestionnaire des utilisations de Slider la Value propriété de l’objet slider pour définir la Rotation propriété du premier Label et utilise la méthode avec la NewValueString.Format propriété des arguments d’événement pour définir la Text propriété de la secondeLabel. Ces deux approches pour obtenir la valeur actuelle de l’objet Slider sont interchangeables.

Voici le programme en cours d’exécution sur les appareils iOS et Android :

Basic Slider Code

La deuxième Label affiche le texte « (non initialisé) » jusqu’à ce que le Slider message soit manipulé, ce qui entraîne le déclenchement du premier ValueChanged événement. Notez que le nombre de décimales affichées est différent pour chaque plateforme. Ces différences sont liées aux implémentations de la Slider plateforme et sont abordées plus loin dans cet article dans la section Différences d’implémentation de la plateforme.

Création d’un curseur en XAML

La page XAML du curseur de base est fonctionnellement identique au code de curseur de base, mais implémentée principalement en XAML :

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="SliderDemos.BasicSliderXamlPage"
             Title="Basic Slider XAML"
             Padding="10, 0">
    <StackLayout>
        <Label x:Name="rotatingLabel"
               Text="ROTATING TEXT"
               FontSize="Large"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

        <Slider Maximum="360"
                ValueChanged="OnSliderValueChanged" />

        <Label x:Name="displayLabel"
               Text="(uninitialized)"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

Le fichier code-behind contient le gestionnaire de l’événement ValueChanged :

public partial class BasicSliderXamlPage : ContentPage
{
    public BasicSliderXamlPage()
    {
        InitializeComponent();
    }

    void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
    {
        double value = args.NewValue;
        rotatingLabel.Rotation = value;
        displayLabel.Text = String.Format("The Slider value is {0}", value);
    }
}

Il est également possible pour le gestionnaire d’événements d’obtenir l’événement Slider qui déclenche l’événement via l’argument sender . La Value propriété contient la valeur actuelle :

double value = ((Slider)sender).Value;

Si l’objet Slider a reçu un nom dans le fichier XAML avec un x:Name attribut (par exemple, « slider »), le gestionnaire d’événements peut référencer cet objet directement :

double value = slider.Value;

Liaison de données avec le curseur

La page Liaisons de curseur de base montre comment écrire un programme presque équivalent qui élimine le gestionnaire d’événements à l’aide de la Value liaison de données :

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="SliderDemos.BasicSliderBindingsPage"
             Title="Basic Slider Bindings"
             Padding="10, 0">
    <StackLayout>
        <Label Text="ROTATING TEXT"
               Rotation="{Binding Source={x:Reference slider},
                                  Path=Value}"
               FontSize="Large"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

        <Slider x:Name="slider"
                Maximum="360" />

        <Label x:Name="displayLabel"
               Text="{Binding Source={x:Reference slider},
                              Path=Value,
                              StringFormat='The Slider value is {0:F0}'}"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

La Rotation propriété du premier Label est liée à la Value propriété du Slidersecond TextLabel avec une StringFormat spécification. La page Liaisons de curseurs de base fonctionne un peu différemment des deux pages précédentes : lorsque la page apparaît d’abord, la deuxième Label affiche la chaîne de texte avec la valeur. Il s’agit d’un avantage d’utiliser la liaison de données. Pour afficher du texte sans liaison de données, vous devez initialiser spécifiquement la Text propriété de l’événement Label ou simuler un déclenchement de l’événement ValueChanged en appelant le gestionnaire d’événements à partir du constructeur de classe.

Précautions

La valeur de la Minimum propriété doit toujours être inférieure à la valeur de la Maximum propriété. L’extrait de code suivant entraîne la Slider levée d’une exception :

// Throws an exception!
Slider slider = new Slider
{
    Minimum = 10,
    Maximum = 20
};

Le compilateur C# génère du code qui définit ces deux propriétés dans la séquence et lorsque la Minimum propriété a la valeur 10, elle est supérieure à la valeur par défaut Maximum 1. Vous pouvez éviter l’exception dans ce cas en définissant la Maximum propriété en premier :

Slider slider = new Slider
{
    Maximum = 20,
    Minimum = 10
};

La valeur Maximum 20 n’est pas un problème, car elle est supérieure à la valeur par défaut Minimum de 0. Quand Minimum elle est définie, la valeur est inférieure à la Maximum valeur 20.

Le même problème existe en XAML. Définissez les propriétés dans un ordre qui garantit qu’elle Maximum est toujours supérieure à Minimum:

<Slider Maximum="20"
        Minimum="10" ... />

Vous pouvez définir les valeurs et les Minimum valeurs sur des nombres négatifs, mais uniquement dans un ordre où Minimum est toujours inférieur à Maximum:Maximum

<Slider Minimum="-20"
        Maximum="-10" ... />

La Value propriété est toujours supérieure ou égale à la Minimum valeur et inférieure ou égale à Maximum. Si Value elle est définie sur une valeur en dehors de cette plage, la valeur est coéchée pour se trouver dans la plage, mais aucune exception n’est levée. Par exemple, ce code ne déclenche pas d’exception :

Slider slider = new Slider
{
    Value = 10
};

Au lieu de cela, la Value propriété est coéchée à la Maximum valeur 1.

Voici un extrait de code illustré ci-dessus :

Slider slider = new Slider
{
    Maximum = 20,
    Minimum = 10
};

Quand Minimum la valeur est 10, elle Value est également définie sur 10.

Si un gestionnaire d’événements ValueChanged a été attaché au moment où la Value propriété est cochée à une autre valeur que sa valeur par défaut 0, un ValueChanged événement est déclenché. Voici un extrait de code XAML :

<Slider ValueChanged="OnSliderValueChanged"
        Maximum="20"
        Minimum="10" />

Quand Minimum la valeur est définie sur 10, Value elle est également définie sur 10 et l’événement ValueChanged est déclenché. Cela peut se produire avant la construction du reste de la page, et le gestionnaire peut tenter de référencer d’autres éléments sur la page qui n’ont pas encore été créés. Vous pouvez ajouter du code au ValueChanged gestionnaire qui case activée des null valeurs d’autres éléments de la page. Vous pouvez également définir le ValueChanged gestionnaire d’événements après l’initialisation des Slider valeurs.

Différences d’implémentation de plateforme

Les captures d’écran affichées précédemment affichent la valeur du Slider fichier avec un nombre différent de décimales. Cela concerne la façon dont l’implémentation Slider est effectuée sur les plateformes Android et UWP.

Implémentation Android

L’implémentation Android est Slider basée sur Android SeekBar et définit toujours la Max propriété sur 1000. Cela signifie que le Slider sur Android n’a que 1 001 valeurs discrètes. Si vous définissez la SliderMinimum valeur 0 et une Maximum valeur de 5 000, alors que la Slider propriété est manipulée, la Value propriété a les valeurs 0, 5, 10, 15, etc.

Implémentation UWP

L’implémentation UWP est Slider basée sur le contrôle UWP Slider . La StepFrequency propriété de l’UWP Slider est définie sur la différence entre les propriétés et Minimum les Maximum propriétés divisées par 10, mais pas supérieures à 1.

Par exemple, pour la plage par défaut de 0 à 1, la StepFrequency propriété est définie sur 0.1. Slider Comme il est manipulé, la Value propriété est limitée à 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 et 1.0. (Ceci est évident dans la dernière page de la Exemple SliderDemos.) Lorsque la différence entre les propriétés et Minimum les Maximum propriétés est de 10 ou supérieure, StepFrequency elle est définie sur 1, et la Value propriété a des valeurs intégrales.

Solution StepSlider

Un plus polyvalent StepSlider est abordé dans le chapitre 27. Convertisseurs personnalisés du livre Création d’applications mobiles avec Xamarin.Forms. Il StepSlider est similaire à Slider mais ajoute une Steps propriété pour spécifier le nombre de valeurs entre Minimum et Maximum.

Curseurs pour la sélection de couleurs

Les deux dernières pages de l’exemple SliderDemos utilisent trois Slider instances pour la sélection de couleurs. La première page gère toutes les interactions dans le fichier code-behind, tandis que la deuxième page montre comment utiliser la liaison de données avec un ViewModel.

Gestion des curseurs dans le fichier code-behind

La page Curseurs de couleur RVB instancie une BoxView couleur, trois Slider instances pour sélectionner les composants rouge, vert et bleu de la couleur, et trois Label éléments pour afficher ces valeurs de couleur :

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="SliderDemos.RgbColorSlidersPage"
             Title="RGB Color Sliders">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Slider">
                <Setter Property="Maximum" Value="255" />
            </Style>

            <Style TargetType="Label">
                <Setter Property="HorizontalTextAlignment" Value="Center" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout Margin="10">
        <BoxView x:Name="boxView"
                 Color="Black"
                 VerticalOptions="FillAndExpand" />

        <Slider x:Name="redSlider"
                ValueChanged="OnSliderValueChanged" />

        <Label x:Name="redLabel" />

        <Slider x:Name="greenSlider"
                ValueChanged="OnSliderValueChanged" />

        <Label x:Name="greenLabel" />

        <Slider x:Name="blueSlider"
                ValueChanged="OnSliderValueChanged" />

        <Label x:Name="blueLabel" />
    </StackLayout>
</ContentPage>

A Style donne aux trois Slider éléments une plage de 0 à 255. Les Slider éléments partagent le même ValueChanged gestionnaire, qui est implémenté dans le fichier code-behind :

public partial class RgbColorSlidersPage : ContentPage
{
    public RgbColorSlidersPage()
    {
        InitializeComponent();
    }

    void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
    {
        if (sender == redSlider)
        {
            redLabel.Text = String.Format("Red = {0:X2}", (int)args.NewValue);
        }
        else if (sender == greenSlider)
        {
            greenLabel.Text = String.Format("Green = {0:X2}", (int)args.NewValue);
        }
        else if (sender == blueSlider)
        {
            blueLabel.Text = String.Format("Blue = {0:X2}", (int)args.NewValue);
        }

        boxView.Color = Color.FromRgb((int)redSlider.Value,
                                      (int)greenSlider.Value,
                                      (int)blueSlider.Value);
    }
}

La première section définit la Text propriété de l’une des Label instances sur une chaîne de texte courte indiquant la valeur de l’élément Slider hexadécimal. Ensuite, les trois Slider instances sont accessibles pour créer une Color valeur à partir des composants RVB :

RGB Color Sliders

Liaison du curseur à un ViewModel

La page Curseurs de couleur HSL montre comment utiliser un ViewModel pour effectuer les calculs utilisés pour créer une Color valeur à partir de valeurs de teinte, de saturation et de luminosité. Comme tous les ViewModels, la HSLColorViewModel classe implémente l’interface INotifyPropertyChanged et déclenche un PropertyChanged événement chaque fois qu’une des propriétés change :

public class HslColorViewModel : INotifyPropertyChanged
{
    Color color;

    public event PropertyChangedEventHandler PropertyChanged;

    public double Hue
    {
        set
        {
            if (color.Hue != value)
            {
                Color = Color.FromHsla(value, color.Saturation, color.Luminosity);
            }
        }
        get
        {
            return color.Hue;
        }
    }

    public double Saturation
    {
        set
        {
            if (color.Saturation != value)
            {
                Color = Color.FromHsla(color.Hue, value, color.Luminosity);
            }
        }
        get
        {
            return color.Saturation;
        }
    }

    public double Luminosity
    {
        set
        {
            if (color.Luminosity != value)
            {
                Color = Color.FromHsla(color.Hue, color.Saturation, value);
            }
        }
        get
        {
            return color.Luminosity;
        }
    }

    public Color Color
    {
        set
        {
            if (color != value)
            {
                color = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Hue"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Saturation"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Luminosity"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Color"));
            }
        }
        get
        {
            return color;
        }
    }
}

ViewModels et l’interface INotifyPropertyChanged sont abordés dans l’article Data Binding.

Le fichier HslColorSlidersPage.xaml instancie et HslColorViewModel le définit sur la propriété de la BindingContext page. Cela permet à tous les éléments du fichier XAML de se lier aux propriétés dans ViewModel :

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:SliderDemos"
             x:Class="SliderDemos.HslColorSlidersPage"
             Title="HSL Color Sliders">

    <ContentPage.BindingContext>
        <local:HslColorViewModel Color="Chocolate" />
    </ContentPage.BindingContext>

    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Label">
                <Setter Property="HorizontalTextAlignment" Value="Center" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout Margin="10">
        <BoxView Color="{Binding Color}"
                 VerticalOptions="FillAndExpand" />

        <Slider Value="{Binding Hue}" />
        <Label Text="{Binding Hue, StringFormat='Hue = {0:F2}'}" />

        <Slider Value="{Binding Saturation}" />
        <Label Text="{Binding Saturation, StringFormat='Saturation = {0:F2}'}" />

        <Slider Value="{Binding Luminosity}" />
        <Label Text="{Binding Luminosity, StringFormat='Luminosity = {0:F2}'}" />
    </StackLayout>
</ContentPage>

À mesure que les Slider éléments sont manipulés, les BoxView éléments sont Label mis à jour à partir de ViewModel :

HSL Color Sliders

Le StringFormat composant de l’extension Binding de balisage est défini pour un format « F2 » pour afficher deux décimales. (La mise en forme de chaîne dans les liaisons de données est abordée dans l’article Mise en forme de chaîne.) Toutefois, la version UWP du programme est limitée aux valeurs 0, 0.1, 0.2, ... 0,9 et 1.0. Il s’agit d’un résultat direct de l’implémentation de l’UWP Slider , comme décrit ci-dessus dans la section Différences d’implémentation de la plateforme.