Xamarin.Forms Suwak

Download Sample Pobieranie przykładu

Użyj suwaka do wybierania z zakresu wartości ciągłych.

Jest Xamarin.FormsSlider to poziomy pasek, który może być manipulowany przez użytkownika w celu wybrania double wartości z zakresu ciągłego.

Definiuje Slider trzy właściwości typu double:

  • Minimum jest minimalną wartością zakresu z wartością domyślną 0.
  • Maximum jest maksymalną wartością zakresu z wartością domyślną 1.
  • Value jest wartością suwaka, która może zawierać zakres między wartościami Minimum i Maximum i ma wartość domyślną 0.

Wszystkie trzy właściwości są wspierane przez BindableProperty obiekty. Właściwość Value ma domyślny tryb BindingMode.TwoWaypowiązania , co oznacza, że jest odpowiedni jako źródło powiązania w aplikacji korzystającej z architektury Model-View-ViewModel (MVVM).

Ostrzeżenie

Wewnętrznie zapewnia Slider , że Minimum wartość jest mniejsza niż Maximum. Jeśli wartość Minimum lub Maximum kiedykolwiek jest ustawiona tak, że Minimum nie jest mniejsza niż Maximum, zgłaszany jest wyjątek. Aby uzyskać więcej informacji na temat ustawiania właściwości iMaximum, zobacz sekcję Środki ostrożności poniżej.Minimum

Właściwość Slider jest przekształcana Value w taki sposób, aby mieściła się między Minimum i Maximum, włącznie. Minimum Jeśli właściwość jest ustawiona na wartość większą niż Value właściwość, Slider właściwość ustawia Value wartość Minimum. Podobnie, jeśli Maximum ustawiono wartość mniejszą niż Value, Slider właściwość ustawia Value wartość na Maximum.

SliderValueChanged Definiuje zdarzenie, które jest wyzwalane, gdy Value zmiany są uruchamiane za pomocą manipulowania Slider przez użytkownika lub, gdy program ustawia Value właściwość bezpośrednio. Zdarzenie ValueChanged jest również wyzwalane, gdy Value właściwość jest coerced zgodnie z opisem w poprzednim akapicie.

Obiekt ValueChangedEventArgs , który towarzyszy ValueChanged zdarzeniu ma dwie właściwości: doublei OldValueNewValue. W momencie uruchomienia zdarzenia wartość NewValue jest taka sama jak Value właściwość Slider obiektu.

Slider definiuje DragStarted również zdarzenia, DragCompleted które są uruchamiane na początku i na końcu akcji przeciągania. ValueChanged W przeciwieństwie do zdarzenia zdarzenia zdarzenia DragStarted i DragCompleted są wyzwalane tylko za pomocą manipulacji użytkownikami .Slider Gdy zdarzenie DragStarted jest uruchamiane, DragStartedCommandjest wykonywany typ ICommand, . Podobnie, gdy DragCompleted zdarzenie jest uruchamiane, DragCompletedCommandjest wykonywany typ , ICommand.

Ostrzeżenie

Nie należy używać nieobsługiwanych opcji układu poziomego , CenterStartlub End za pomocą polecenia Slider. Zarówno w systemie Android, jak i uwP, Slider zwija się na słupek o zerowej długości, a w systemie iOS pasek jest bardzo krótki. Zachowaj ustawienie domyślne HorizontalOptions elementu Filli nie używaj szerokości Auto podczas umieszczania SliderGrid w układzie.

Definiuje Slider również kilka właściwości, które wpływają na jej wygląd:

Uwaga

Właściwości ThumbColor i ThumbImageSource wzajemnie się wykluczają. Jeśli obie właściwości są ustawione, ThumbImageSource właściwość będzie mieć pierwszeństwo.

Kod i znaczniki suwaka podstawowego

Przykład SliderDemos zaczyna się od trzech stron, które są funkcjonalnie identyczne, ale są implementowane na różne sposoby. Pierwsza strona używa tylko kodu C#, drugi używa języka XAML z procedurą obsługi zdarzeń w kodzie, a trzecia jest w stanie uniknąć obsługi zdarzeń przy użyciu powiązania danych w pliku XAML.

Tworzenie suwaka w kodzie

Na stronie Kod suwaka podstawowego w przykładzie SliderDemos pokazano, jak utworzyć i Slider dwa Label obiekty w kodzie:

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

Właściwość Slider jest inicjowana jako Maximum właściwość 360. Procedura obsługi używa właściwości obiektu do ustawienia Rotation właściwości pierwszego Label i używa String.Format metody z właściwością NewValue argumentów zdarzeń, aby ustawić Text właściwość drugiego Labelobiektu .sliderValueSliderValueChanged Te dwa podejścia do uzyskania bieżącej Slider wartości są zamienne.

Oto program uruchomiony na urządzeniach z systemami iOS i Android:

Basic Slider Code

Drugi Label wyświetla tekst "(niezainicjowany)", dopóki Slider nie zostanie zmanipulowany, co powoduje wyzwolenie pierwszego ValueChanged zdarzenia. Zwróć uwagę, że liczba wyświetlanych miejsc dziesiętnych jest inna dla każdej platformy. Te różnice są związane z implementacjami Slider platformy programu i zostały omówione w dalszej części tego artykułu w sekcji Różnice implementacji platformy.

Tworzenie suwaka w języku XAML

Strona XAML suwaka podstawowego jest funkcjonalnie taka sama jak podstawowy kod suwaka, ale zaimplementowana głównie w języku 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>

Plik związany z kodem zawiera procedurę obsługi zdarzenia 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);
    }
}

Program obsługi zdarzeń może również uzyskać Slider wyzwalanie zdarzenia za pomocą argumentu sender . Właściwość Value zawiera bieżącą wartość:

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

Slider Jeśli obiekt otrzymał nazwę w pliku XAML z atrybutem x:Name (na przykład "slider"), program obsługi zdarzeń może odwoływać się bezpośrednio do tego obiektu:

double value = slider.Value;

Powiązanie danych suwaka

Na stronie Podstawowe powiązania suwaka pokazano, jak napisać niemal równoważny program eliminujący Value procedurę obsługi zdarzeń przy użyciu powiązania danych:

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

Właściwość Rotation pierwszego Label jest powiązana Value z właściwością Slider, podobnie jak Text właściwość drugiego ze specyfikacjąStringFormat.Label Strona Podstawowe powiązania suwaka działa nieco inaczej niż na dwóch poprzednich stronach: Po pierwszym wyświetleniu strony drugi Label wyświetla ciąg tekstowy z wartością . Jest to korzyść z używania powiązania danych. Aby wyświetlić tekst bez powiązania danych, należy w szczególności zainicjować Text właściwość Label obiektu lub zasymulować wyzwalanie ValueChanged zdarzenia przez wywołanie procedury obsługi zdarzeń z konstruktora klasy.

Środki ostrożności

Wartość Minimum właściwości musi być zawsze mniejsza niż wartość Maximum właściwości. Poniższy fragment kodu powoduje wystąpienie wyjątku Slider :

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

Kompilator języka C# generuje kod, który ustawia te dwie właściwości w sekwencji, a gdy Minimum właściwość jest ustawiona na 10, jest większa niż wartość domyślna Maximum 1. Można uniknąć wyjątku w tym przypadku, ustawiając Maximum najpierw właściwość:

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

Ustawienie Maximum wartości 20 nie jest problemem, ponieważ jest większe niż wartość domyślna Minimum 0. Po Minimum ustawieniu wartość jest mniejsza niż Maximum wartość 20.

Ten sam problem występuje w języku XAML. Ustaw właściwości w kolejności, która gwarantuje, że Maximum wartość jest zawsze większa niż Minimum:

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

Wartości i można ustawić Minimum na liczby ujemne, ale tylko w kolejności, w której Minimum wartość jest zawsze mniejsza niż Maximum:Maximum

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

Właściwość Value jest zawsze większa lub równa Minimum wartości i mniejsza niż lub równa Maximum. Jeśli Value zostanie ustawiona wartość poza tym zakresem, wartość będzie zmuszana do leżenia w zakresie, ale nie zostanie zgłoszony żaden wyjątek. Na przykład ten kod nie zgłosi wyjątku:

Slider slider = new Slider
{
    Value = 10
};

Value Zamiast tego właściwość jest coerced na Maximum wartość 1.

Poniżej przedstawiono fragment kodu:

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

Gdy Minimum jest ustawiona wartość 10, wartość Value jest również ustawiona na 10.

ValueChanged Jeśli program obsługi zdarzeń został dołączony w momencie, Value gdy właściwość jest coerced do czegoś innego niż jego domyślna wartość 0, ValueChanged zdarzenie zostanie wyzwolone. Oto fragment kodu XAML:

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

Gdy Minimum wartość jest ustawiona na 10, Value jest również ustawiona na 10, a ValueChanged zdarzenie zostanie wyzwolone. Może się to zdarzyć przed utworzeniem pozostałej części strony, a program obsługi może próbować odwołać się do innych elementów na stronie, które nie zostały jeszcze utworzone. Możesz dodać kod do ValueChanged programu obsługi, który sprawdza null wartości innych elementów na stronie. Można też ustawić procedurę ValueChanged obsługi zdarzeń po Slider zainicjowaniu wartości.

Różnice implementacji platformy

Pokazane wcześniej zrzuty ekranu przedstawiają wartość Slider z inną liczbą punktów dziesiętnych. Dotyczy to sposobu implementacji na Slider platformach Android i UWP.

Implementacja systemu Android

Implementacja Slider systemu Android jest oparta na systemie Android SeekBar i zawsze ustawia Max właściwość na 1000. Oznacza to, że Slider w systemie Android jest tylko 1001 wartości dyskretnych. Jeśli dla właściwości ustawiono SliderMinimum wartość 0 i Maximum 5000, właściwość SliderValue ma wartości 0, 10, 15 itd.

Implementacja platformy UWP

Implementacja platformy UNIWERSALNEJ systemu Slider Windows jest oparta na kontrolce platformy UWP Slider . Właściwość StepFrequency platformy UWP Slider jest ustawiona na różnicę Maximum właściwości i Minimum podzieloną przez 10, ale nie większą niż 1.

Na przykład dla domyślnego zakresu od 0 do 1 StepFrequency właściwość jest ustawiona na 0,1. W miarę Slider manipulowania Value właściwość jest ograniczona do wartości 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 i 1.0. (Jest to widoczne na ostatniej stronie w Przykład SliderDemos ). Gdy różnica między właściwościami Maximum i Minimum wynosi 10 lub większa, StepFrequency jest ustawiona na 1, a Value właściwość ma wartości całkowite.

Rozwiązanie StepSlider

Bardziej wszechstronny jest omówiony w rozdziale StepSlider 27. Niestandardowe programy renderowania książki Creating Mobile Apps with Xamarin.Forms. Właściwość jest podobna StepSlider do Slider , ale dodaje Steps właściwość , aby określić liczbę wartości między Minimum i Maximum.

Suwaki wyboru kolorów

Ostatnie dwie strony w przykładzie SliderDemos używają trzech Slider wystąpień do wyboru kolorów. Pierwsza strona obsługuje wszystkie interakcje w pliku za pomocą kodu, a druga strona pokazuje, jak używać powiązania danych z modelem ViewModel.

Obsługa suwaków w pliku za pomocą kodu

Strona Suwaki kolorów RGB tworzy wystąpienie elementu w BoxView celu wyświetlenia koloru, trzech Slider wystąpień do wybrania czerwonych, zielonych i niebieskich składników koloru oraz trzech Label elementów do wyświetlania tych wartości kolorów:

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

Element A Style daje wszystkie trzy Slider elementy z zakresu od 0 do 255. Slider Elementy współużytkuje tę samą ValueChanged procedurę obsługi, która jest implementowana w pliku za kodem:

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

Pierwsza sekcja ustawia Text właściwość jednego z Label wystąpień na krótki ciąg tekstowy wskazujący wartość Slider w szesnastkowym. Następnie dostęp do wszystkich trzech Slider wystąpień jest uzyskiwany w celu utworzenia Color wartości na podstawie składników RGB:

RGB Color Sliders

Wiązanie suwaka z modelem ViewModel

Na stronie Suwaki kolorów HSL pokazano, jak używać modelu ViewModel do wykonywania obliczeń używanych do tworzenia Color wartości na podstawie odcieni, nasycenia i jasności. Podobnie jak w przypadku wszystkich modeli ViewModel, klasa implementuje INotifyPropertyChangedPropertyChanged interfejs i uruchamia zdarzenie za każdym razem, HSLColorViewModel gdy jedna z właściwości ulegnie zmianie:

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

Modele widoków i INotifyPropertyChanged interfejs zostały omówione w artykule Powiązanie danych.

Plik HslColorSlidersPage.xaml tworzy wystąpienie HslColorViewModel obiektu i ustawia go na właściwość strony BindingContext . Dzięki temu wszystkie elementy w pliku XAML mogą być powiązane z właściwościami w modelu 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>

Slider Gdy elementy są manipulowane, BoxView elementy i Label są aktualizowane z modelu ViewModel:

HSL Color Sliders

Składnik StringFormatBinding rozszerzenia znaczników jest ustawiony dla formatu "F2", aby wyświetlić dwa miejsca dziesiętne. (Formatowanie ciągu w powiązaniach danych zostało omówione w artykule Formatowanie ciągu). Jednak wersja platformy UWP programu jest ograniczona do wartości 0, 0,1, 0,2, ... 0.9 i 1.0. Jest to bezpośredni wynik implementacji platformy UWP Slider , jak opisano powyżej w sekcji Różnice implementacji platformy.