Xamarin.Forms Slider

Download Sample Скачайте пример

Используйте ползунок для выбора из диапазона непрерывных значений.

Это Xamarin.FormsSlider горизонтальная полоса, которая может управляться пользователем, чтобы выбрать double значение из непрерывного диапазона.

Определяет Slider три свойства типа double:

  • Minimum — минимальное значение диапазона с значением по умолчанию 0.
  • Maximum — максимальное значение диапазона с значением по умолчанию 1.
  • Value — это значение ползунка, которое может варьироваться между Minimum и Maximum имеет значение по умолчанию 0.

Все три свойства поддерживаются объектами BindableProperty . Свойство Value имеет режим BindingMode.TwoWayпривязки по умолчанию, что означает, что он подходит в качестве источника привязки в приложении, использующем архитектуру Model-ViewModel (MVVM).

Предупреждение

Внутри системы гарантирует, Slider что Minimum меньше Maximum. Если Minimum или Maximum когда-либо заданы таким образом, что Minimum не меньше Maximum, возникает исключение. Дополнительные сведения о настройке Minimum и Maximum свойствах см. в разделе "Меры предосторожности" ниже.

Принуживает SliderValue свойство таким образом, чтобы оно было между Minimum и Maximum, включительно. Minimum Если для свойства задано значение, большее, чем Value свойство, Slider задает Value значение Minimumсвойства. Аналогичным образом, если Maximum задано значение меньше Value, то Slider свойство имеет значение ValueMaximum.

SliderValueChanged определяет событие, которое запускается при Value изменении, либо с помощью пользовательской манипуляции Slider с этим свойством, либо при непосредственном установке Value свойства. Событие ValueChanged также запускается, когда Value свойство принуждается, как описано в предыдущем абзаце.

ОбъектValueChangedEventArgs, сопровождающий ValueChanged событие, имеет два свойства: и NewValueтипdoubleOldValue. Во время запуска события значение NewValue совпадает со Value свойством Slider объекта.

Slider также определяет DragStarted и DragCompleted события, которые запускаются в начале и конце действия перетаскивания. ValueChanged В отличие от события, DragStarted события запускаются DragCompleted только с помощью манипуляции пользователемSlider. DragStarted При срабатывании DragStartedCommandсобытия выполняется тип , типICommand. Аналогичным образом, когда DragCompleted событие запускается, DragCompletedCommandвыполняется тип , тип ICommand.

Предупреждение

Не используйте не ограниченные параметры горизонтального макета Center, Startили End с Slider. Как в Android, так и в UWP, Slider сворачивается на полосу нулевой длины, а на iOS панель очень коротка. Сохраните параметр Fillпо умолчанию HorizontalOptions и не используйте ширину Auto при вводе SliderGrid в макет.

Также Slider определяется несколько свойств, влияющих на его внешний вид:

Примечание.

ThumbImageSource Свойства ThumbColor являются взаимоисключающими. Если заданы оба свойства, ThumbImageSource то свойство будет иметь приоритет.

Базовый код ползунка и разметка

Пример SliderDemos начинается с трех страниц, которые функционально идентичны, но реализуются разными способами. Первая страница использует только код C#, второй использует XAML с обработчиком событий в коде, а третий способен избежать обработчика событий с помощью привязки данных в XAML-файле.

Создание ползунка в коде

На странице "Базовый код ползунка" в примере SliderDemos показано, как создать Slider и два Label объекта в коде:

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

Инициализировано SliderMaximum свойство 360. Обработчик ValueChangedSlider объекта использует Value свойство slider объекта для задания Rotation свойства первого Label и использует String.Format метод со NewValue свойством аргументов события для задания Text свойства второго Label. Эти два подхода для получения текущего Slider значения являются взаимозаменяемыми.

Ниже приведена программа, запущенная на устройствах iOS и Android:

Basic Slider Code

Label Второй отображает текст "(неинициализированный)" до тех пор, пока не Slider будет манипулировано, что приводит к тому, что первое ValueChanged событие будет запущено. Обратите внимание, что число отображаемых десятичных разрядов отличается для каждой платформы. Эти различия связаны с реализацией платформы и рассматриваются далее в этой статье в разделе "Различия в реализации Slider платформы".

Создание ползунка в XAML

Страница XAML "Базовый ползунок" функционально аналогична базовому коду ползунка, но реализована в основном в 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>

Файл программной части содержит обработчик события 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);
    }
}

Кроме того, обработчик событий может получить Slider событие с помощью аргумента sender . Свойство Value содержит текущее значение:

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

Slider Если объект получил имя в XAML-файле с атрибутом x:Name (например, "ползунок"), обработчик событий может ссылаться непосредственно на этот объект:

double value = slider.Value;

Привязка данных ползунка

На странице "Базовые привязки ползунка" показано, как создать почти эквивалентную программу, которая устраняет Value обработчик событий с помощью привязки данных:

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

Свойство Rotation первого привязано к Value свойству Sliderобъекта , как Text и свойство второго LabelLabel со StringFormat спецификацией. Страница "Базовые привязки ползунка" немного отличается от двух предыдущих страниц: при первом появлении страницы вторая Label отображает текстовую строку со значением. Это преимущество использования привязки данных. Чтобы отобразить текст без привязки данных, необходимо специально инициализировать Text свойство Label события или имитировать запуск ValueChanged события путем вызова обработчика событий из конструктора класса.

Меры предосторожности

Значение Minimum свойства всегда должно быть меньше значения Maximum свойства. Следующий фрагмент кода приводит Slider к возникновению исключения:

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

Компилятор C# создает код, который задает эти два свойства в последовательности, и если Minimum свойство имеет значение 10, оно больше значения по умолчанию Maximum 1. Чтобы избежать исключения в этом случае, сначала задав Maximum свойство:

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

Значение Maximum 20 не является проблемой, так как значение по умолчанию Minimum больше 0. Если Minimum задано, значение меньше Maximum 20.

Та же проблема существует в XAML. Задайте свойства в порядке, обеспечивающем, что Maximum всегда больше Minimum:

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

Можно задать Minimum отрицательные числа и Maximum значения, но только в порядке, где Minimum всегда меньше Maximum:

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

Свойство Value всегда больше или равно значению Minimum и меньше или равно Maximum. Если Value задано значение за пределами этого диапазона, значение будет принудиться к тому, чтобы лежать в диапазоне, но исключение не возникает. Например, этот код не будет вызывать исключение:

Slider slider = new Slider
{
    Value = 10
};

Вместо этого Value свойство принудается к Maximum значению 1.

Ниже приведен фрагмент кода, показанный выше:

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

Если Minimum задано значение 10, то Value также имеет значение 10.

ValueChanged Если обработчик событий был присоединен в то время, когда Value свойство принудается к чему-либо, отличному от его значения по умолчанию 0, ValueChanged то событие запускается. Ниже приведен фрагмент КОДА XAML:

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

Если Minimum задано значение 10, Value также имеет значение 10, а ValueChanged событие запускается. Это может произойти до создания остальной части страницы, и обработчик может попытаться ссылаться на другие элементы на странице, которые еще не созданы. Может потребоваться добавить код в ValueChanged обработчик, который проверка для null значений других элементов на странице. Кроме того, можно задать ValueChanged обработчик событий после инициализации значений Slider .

Различия в реализации платформы

На снимках экрана, показанных ранее, отображается значение Slider с другим числом десятичных точек. Это связано с тем, как Slider реализуется на платформах Android и UWP.

Реализация Android

Реализация Slider Android основана на Android SeekBar и всегда задает Max для свойства значение 1000. Это означает, что Slider в Android есть только 1001 дискретных значений. Если задано SliderMinimum значение 0 и Maximum 5000, то при Slider обработке Value свойство имеет значения 0, 5, 10, 15 и т. д.

Реализация UWP

Реализация Slider UWP основана на элементе управления UWP Slider . Свойство StepFrequency UWP Slider имеет разницу Maximum между свойствами, Minimum разделенными на 10, но не более 1.

Например, для диапазона по умолчанию от 0 до 1 StepFrequency свойство имеет значение 0,1. Slider По мере управления Value свойство ограничено 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 и 1.0. (Это очевидно на последней странице в Пример SliderDemos .) Если разница между Maximum свойствами и Minimum свойствами составляет 10 или больше, то StepFrequency имеет значение 1, а Value свойство имеет целочисленные значения.

Решение StepSlider

Более универсальный StepSlider обсуждается в главе 27. Пользовательские отрисовщики книги " Создание мобильных приложений с Xamarin.Formsпомощью . Аналогично, StepSliderSlider но добавляет Steps свойство для указания количества значений между Minimum и Maximum.

Ползунки для выбора цвета

Последние две страницы в примере SliderDemos используют три Slider экземпляра для выбора цвета. Первая страница обрабатывает все взаимодействия в файле программной части, а на второй странице показано, как использовать привязку данных с ViewModel.

Обработка ползунков в файле программной части

Страница цветных ползунков RGB создает BoxView экземпляр цвета, три Slider экземпляра для выбора красных, зеленых и синих компонентов цвета и трех Label элементов для отображения этих значений цвета:

<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 предоставляет все три Slider элемента диапазон от 0 до 255. Элементы Slider используют один и тот же ValueChanged обработчик, который реализуется в файле программной части:

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

Первый раздел задает Text свойство одного из Label экземпляров короткой текстовой строке, указывающей значение Slider шестнадцатеричного значения. Затем доступ к всем трем Slider экземплярам создается для создания Color значения из компонентов RGB:

RGB Color Sliders

Привязка ползунка к ViewModel

На странице "Цветные ползунки HSL" показано, как использовать ViewModel для выполнения вычислений, используемых для создания Color значения из оттенка, насыщенности и значения света. Как и все ViewModels, HSLColorViewModel класс реализует INotifyPropertyChanged интерфейс и запускает PropertyChanged событие при каждом изменении одного из свойств:

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 и INotifyPropertyChanged интерфейс рассматриваются в статье "Привязка данных".

Файл HslColorSlidersPage.xaml создает экземпляр HslColorViewModel и задает его свойству страницы BindingContext . Это позволяет всем элементам в XAML-файле привязаться к свойствам в 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 По мере управления BoxViewLabel элементами элементы обновляются из ViewModel:

HSL Color Sliders

Компонент StringFormat расширения разметки Binding задается для формата "F2" для отображения двух десятичных разрядов. (Форматирование строк в привязках данных рассматривается в статье Форматирование строк.) Однако версия программы UWP ограничена значениями 0, 0.1, 0.2, ... 0.9 и 1.0. Это прямой результат реализации UWP Slider , как описано выше в разделе "Различия в реализации платформы".