Xamarin.Forms Schieberegler

Download Sample Das Beispiel herunterladen

Verwenden Sie einen Schieberegler, um aus einem Bereich fortlaufender Werte auszuwählen.

Dies Xamarin.FormsSlider ist ein horizontaler Balken, der vom Benutzer bearbeitet werden kann, um einen double Wert aus einem fortlaufenden Bereich auszuwählen.

Dies Slider definiert drei Eigenschaften des Typs double:

  • Minimum ist das Minimum des Bereichs, mit einem Standardwert von 0.
  • Maximum ist das Maximum des Bereichs mit dem Standardwert 1.
  • Value ist der Wert des Schiebereglers, der zwischen Minimum und Maximum dem Standardwert 0 liegen kann.

Alle drei Eigenschaften werden von BindableProperty Objekten unterstützt. Die Value Eigenschaft verfügt über einen Standardbindungsmodus , BindingMode.TwoWaywas bedeutet, dass sie als Bindungsquelle in einer Anwendung geeignet ist, die die Model-View-ViewModel (MVVM) -Architektur verwendet.

Warnung

Intern stellt der Slider sicher, dass Minimum kleiner als Maximum ist. Wenn Minimum oder Maximum jemals so gesetzt werden, dass Minimum nicht kleiner als Maximum ist, wird eine Ausnahme ausgelöst. Weitere Informationen zum Festlegen der Minimum Eigenschaften Maximum finden Sie im Abschnitt "Vorsichtsmaßnahmen" weiter unten.

Der Slider erzwingt die Value-Eigenschaft, sodass sie zwischen Minimum und Maximum einschließlich liegt. Wenn die Minimum-Eigenschaft auf einen größeren Wert als die Value-Eigenschaft gesetzt wird, setzt der Slider die Value-Eigenschaft auf Minimum. Wenn Maximum auf einen kleineren Wert als Value gesetzt wird, setzt der Slider die Value-Eigenschaft auf Maximum.

Slider definiert ein ValueChanged Ereignis, das ausgelöst wird, wenn die Value Änderungen entweder durch die Benutzermanipulation des Slider Oder durch das Programm die Value Eigenschaft direkt festgelegt werden. Ein ValueChanged Ereignis wird auch ausgelöst, wenn die Value Eigenschaft wie im vorherigen Absatz beschrieben umgewandelt wird.

Das ValueChangedEventArgs Objekt, das das ValueChanged Ereignis begleitet, verfügt über zwei Eigenschaften vom Typ double: OldValue und NewValue. Beim Auslösen des Ereignisses entspricht der Wert NewValue der Value Eigenschaft des Slider Objekts.

Slider definiert DragStarted und DragCompleted Ereignisse, die am Anfang und Ende der Ziehaktion ausgelöst werden. ValueChanged Im Gegensatz zum Ereignis werden die DragStarted Ereignisse DragCompleted und Ereignisse nur durch die Benutzermanipulation der Slider. Wenn das DragStarted-Ereignis ausgelöst wird, wird der DragStartedCommand vom Typ ICommand ausgeführt. Wenn das DragCompleted-Ereignis ausgelöst wird, wird der DragCompletedCommand vom Typ ICommand ausgeführt.

Warnung

Verwenden Sie nicht die uneingeschränkten horizontalen Layoutoptionen Center, Start oder End mit Slider. Sowohl auf Android als auch auf der UWP reduziert sich der Slider Balken auf einen Balken der Länge Null und auf iOS ist der Balken sehr kurz. Behalten Sie die Standardeinstellung HorizontalOptions von Fill bei und verwenden Sie nicht die Auto-Breite, wenn Sie den Slider in ein Grid-Layout einfügen.

Außerdem Slider werden mehrere Eigenschaften definiert, die sich auf ihre Darstellung auswirken:

Hinweis

Die Eigenschaften ThumbColor und ThumbImageSource schließen sich gegenseitig aus. Wenn beide Eigenschaften gesetzt sind, hat die Eigenschaft ThumbImageSource Vorrang.

Einfacher Schiebereglercode und Markup

Das SliderDemos-Beispiel beginnt mit drei Seiten, die funktional identisch sind, aber auf unterschiedliche Weise implementiert werden. Die erste Seite verwendet nur C#-Code, der zweite verwendet XAML mit einem Ereignishandler im Code, und der dritte kann den Ereignishandler vermeiden, indem die Datenbindung in der XAML-Datei verwendet wird.

Erstellen eines Schiebereglers im Code

Auf der Seite "Einfacher Schiebereglercode" im SliderDemos-Beispiel wird gezeigt, wie sie ein Slider und zwei Label Objekte im Code erstellen:

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
            }
        };
    }
}

Die Slider Initialisierung erfolgt über eine Maximum Eigenschaft von 360. Der ValueChanged Handler der Slider Objekt verwendet die Value Eigenschaft des slider Objekts, um die Rotation Eigenschaft des ersten Label festzulegen, und verwendet die String.Format Methode mit der NewValue Eigenschaft der Ereignisargumente, um die Text Eigenschaft der zweiten Labelfestzulegen. Diese beiden Ansätze zum Abrufen des aktuellen Werts der Slider sind austauschbar.

Hier sehen Sie das Programm, das auf iOS- und Android-Geräten ausgeführt wird:

Basic Slider Code

Im zweiten Label Wird der Text "(nicht initialisiert)" angezeigt, bis die Slider Bearbeitung erfolgt, wodurch das erste ValueChanged Ereignis ausgelöst wird. Beachten Sie, dass die Anzahl der angezeigten Dezimalstellen für jede Plattform unterschiedlich ist. Diese Unterschiede beziehen sich auf die Plattformimplementierungen und Slider werden weiter unten in diesem Artikel im Abschnitt Plattformimplementierungsunterschiede erläutert.

Erstellen eines Schiebereglers in XAML

Die XAML-Seite "Standardschieberegler" ist funktional mit dem Standardschiebereglercode identisch, wird jedoch hauptsächlich in XAML implementiert:

<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>

Die CodeBehind-Datei enthält den Handler für das ValueChanged- Ereignis:

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);
    }
}

Es ist auch möglich, dass der Ereignishandler den Slider, der das Ereignis auslöst, über das sender-Argument erhält. Die Value-Eigenschaft enthält den aktuellen Wert:

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

Wenn dem Slider-Objekt in der XAML-Datei ein Name mit einem x:Name-Attribut zugewiesen würde (z. B. „Schieberegler“), könnte der Ereignishandler direkt auf dieses Objekt verweisen:

double value = slider.Value;

Datenbindung des Schiebereglers

Auf der Seite "Einfache Schiebereglerbindungen" wird gezeigt, wie Sie ein nahezu gleichwertiges Programm schreiben, das den Value Ereignishandler mithilfe der Datenbindung beseitigt:

<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>

Die Rotation Eigenschaft des ersten Label ist an die Value Eigenschaft der Slider, wie die Text Eigenschaft des zweiten Label mit einer StringFormat Spezifikation gebunden. Die Seite "Basic Slider Bindings " funktioniert etwas anders als die beiden vorherigen Seiten: Wenn die Seite zuerst angezeigt wird, zeigt die zweite Label die Textzeichenfolge mit dem Wert an. Dies ist ein Vorteil der Verwendung der Datenbindung. Um Text ohne Datenbindung anzuzeigen, müssen Sie die Text-Eigenschaft des Label spezifisch initialisieren oder das Auslösen des ValueChanged-Ereignisses simulieren, indem Sie den Ereignishandler im Klassenkonstruktor aufrufen.

Vorsichtsmaßnahmen

Der Wert der Eigenschaft Minimum muss immer kleiner sein als der Wert der Eigenschaft Maximum. Der folgende Codeausschnitt löst eine Slider Ausnahme aus:

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

Der C#-Compiler generiert Code, der diese beiden Eigenschaften nacheinander setzt, und wenn die Eigenschaft Minimum auf 10 gesetzt wird, ist sie größer als der Standard-Maximum-Wert von 1. Sie können die Ausnahme in diesem Fall vermeiden, indem Sie zuerst die Eigenschaft Maximum setzen:

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

Die Einstellung Maximum auf 20 ist kein Problem, da sie größer als der Standardwert Minimum 0 ist. Wenn Minimum gesetzt ist, ist der Wert kleiner als der Maximum-Wert von 20.

Dasselbe Problem besteht in XAML. Legen Sie die Eigenschaften in einer Reihenfolge fest, die sicherstellt, dass Maximum immer größer ist als Minimum:

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

Sie können die Werte von Minimum und Maximum auf negative Zahlen setzen, aber nur in einer Reihenfolge, in der Minimum immer kleiner als Maximum ist:

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

Die Eigenschaft Value ist immer größer als oder gleich dem Wert Minimum und kleiner als oder gleich Maximum. Wenn Value auf einen Wert außerhalb dieses Bereichs gesetzt wird, wird der Wert in den Bereich gezwungen, aber es wird keine Ausnahme ausgelöst. Dieser Code löst beispielsweise keine Ausnahme aus:

Slider slider = new Slider
{
    Value = 10
};

Stattdessen wird die Eigenschaft Value auf den Maximum-Wert von 1 gezwungen.

Nachfolgend sehen Sie einen Codeausschnitt, der oben gezeigt wird:

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

Wenn Minimum auf 10 gesetzt wird, wird auch Value auf 10 gesetzt.

Wenn ein ValueChanged Ereignishandler zu dem Zeitpunkt angefügt wurde, zu dem die Value Eigenschaft an einen anderen Wert als den Standardwert 0 umgewandelt wird, wird ein ValueChanged Ereignis ausgelöst. Hier sehen Sie einen Xaml-Codeausschnitt:

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

Wenn Minimum sie auf 10 festgelegt ist, Value wird sie auch auf 10 festgelegt, und das ValueChanged Ereignis wird ausgelöst. Dies kann geschehen, bevor der Rest der Seite erstellt wurde, und der Handler könnte versuchen, auf andere Elemente der Seite zu verweisen, die noch nicht erstellt wurden. Sie können dem ValueChanged-Handler Code hinzufügen, der die null-Werte anderer Elemente auf der Seite überprüft. Oder Sie können den ValueChanged-Ereignishandler setzen, nachdem die Slider-Werte initialisiert wurden.

Unterschiede bei der Plattformimplementierung

Die zuvor gezeigten Screenshots zeigen den Wert des Slider Werts mit einer anderen Anzahl von Dezimalstellen an. Dies bezieht sich auf die Implementierung der Slider Android- und UWP-Plattformen.

Die Android-Implementierung

Die Android-Implementierung Slider basiert auf android SeekBar und legt die Max Eigenschaft immer auf 1000 fest. Dies bedeutet, dass auf Slider Android nur 1.001 diskrete Werte enthalten sind. Wenn Sie die Slider Eigenschaft auf Minimum 0 und Maximum 5000 festlegen, hat die Value Eigenschaft, wie sie Slider bearbeitet wird, Werte von 0, 5, 10, 15 usw.

Die UWP-Implementierung

Die UWP-Implementierung Slider basiert auf dem UWP-Steuerelement Slider . Die StepFrequency Eigenschaft der UWP Slider wird auf die Differenz der Maximum und Minimum eigenschaften geteilt durch 10, jedoch nicht größer als 1 festgelegt.

For example, for the default range of 0 to 1, the StepFrequency property is set to 0.1. Wie die Slider Eigenschaft bearbeitet wird, ist die Value Eigenschaft auf 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 und 1.0 beschränkt. (Dies ist auf der letzten Seite in der SliderDemos-Beispiel .) Wenn der Unterschied zwischen den Maximum Eigenschaften Minimum 10 oder größer ist, wird sie StepFrequency auf 1 festgelegt, und die Value Eigenschaft hat integrale Werte.

Die StepSlider-Lösung

Eine vielseitigere StepSlider Wird in Kapitel 27 erörtert. Benutzerdefinierte Renderer des Buchs Erstellen mobiler Apps mit Xamarin.Forms. Dies StepSlider ist vergleichbar, Slider fügt aber eine Steps Eigenschaft hinzu, um die Anzahl der Werte zwischen Minimum und Maximum.

Schieberegler für die Farbauswahl

Die letzten beiden Seiten im SliderDemos-Beispiel verwenden Slider drei Instanzen für die Farbauswahl. Die erste Seite behandelt alle Interaktionen in der CodeBehind-Datei, während die zweite Seite zeigt, wie Die Datenbindung mit einem ViewModel verwendet wird.

Behandeln von Schiebereglern in der CodeBehind-Datei

Die RGB-Farbschiebereglerseite instanziiert eine BoxView Farbe, drei Slider Instanzen zum Auswählen der Rot-, Grün- und Blaukomponenten der Farbe sowie drei Label Elemente zum Anzeigen dieser Farbwerte:

<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 gibt alle drei Slider Elemente einen Bereich von 0 bis 255. Die Slider Elemente verwenden denselben ValueChanged Handler, der in der CodeBehind-Datei implementiert wird:

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);
    }
}

Im ersten Abschnitt wird die Text Eigenschaft einer der Label Instanzen auf eine kurze Textzeichenfolge festgelegt, die den Wert des Slider Hexadezimalzeichens angibt. Anschließend wird auf alle drei Slider Instanzen zugegriffen, um einen Color Wert aus den RGB-Komponenten zu erstellen:

RGB Color Sliders

Binden des Schiebereglers an ein ViewModel

Auf der Seite "HSL-Farbschieberegler " wird gezeigt, wie Sie mit einem ViewModel die Berechnungen ausführen, die zum Erstellen eines Color Werts aus Farbton-, Sättigungs- und Leuchtdichtewerten verwendet werden. Wie alle ViewModels implementiert die HSLColorViewModel Klasse die INotifyPropertyChanged Schnittstelle und löst ein PropertyChanged Ereignis aus, wenn eine der Eigenschaften geändert wird:

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 und die INotifyPropertyChanged Schnittstelle werden im Artikel "Datenbindung" erläutert.

Die Datei HslColorSlidersPage.xaml instanziiert die HslColorViewModel Datei und legt sie auf die Eigenschaft der Seite BindingContext fest. Dadurch können alle Elemente in der XAML-Datei an Eigenschaften im ViewModel gebunden werden:

<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>

Wenn die Slider Elemente bearbeitet werden, werden die BoxView Elemente Label aus dem ViewModel aktualisiert:

HSL Color Sliders

Die StringFormat Komponente der Binding Markuperweiterung wird für ein Format von "F2" festgelegt, um zwei Dezimalstellen anzuzeigen. (Zeichenfolgenformatierung in Datenbindungen wird im Artikel erläutertZeichenfolgenformatierung.) Die UWP-Version des Programms ist jedoch auf Werte von 0, 0,1, 0,2 beschränkt, ... 0.9 und 1.0. Dies ist ein direktes Ergebnis der Implementierung der UWP Slider , wie oben im Abschnitt Plattformimplementierungsunterschiede beschrieben.