Xamarin.Forms Slider
Используйте ползунок для выбора из диапазона непрерывных значений.
Это 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
свойствах см. в разделе "Меры предосторожности" ниже.
Принуживает Slider
Value
свойство таким образом, чтобы оно было между Minimum
и Maximum
, включительно. Minimum
Если для свойства задано значение, большее, чем Value
свойство, Slider
задает Value
значение Minimum
свойства. Аналогичным образом, если Maximum
задано значение меньше Value
, то Slider
свойство имеет значение Value
Maximum
.
Slider
ValueChanged
определяет событие, которое запускается при Value
изменении, либо с помощью пользовательской манипуляции Slider
с этим свойством, либо при непосредственном установке Value
свойства. Событие ValueChanged
также запускается, когда Value
свойство принуждается, как описано в предыдущем абзаце.
ОбъектValueChangedEventArgs
, сопровождающий ValueChanged
событие, имеет два свойства: и NewValue
типdouble
OldValue
. Во время запуска события значение 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
при вводе Slider
Grid
в макет.
Также Slider
определяется несколько свойств, влияющих на его внешний вид:
MinimumTrackColor
— цвет полосы в левой части отпечатка.MaximumTrackColor
— цвет панели справа от пальца.ThumbColor
— это цвет отпечатка.ThumbImageSource
— это изображение, используемое для большого пальца, типаImageSource
.
Примечание.
ThumbImageSource
Свойства ThumbColor
являются взаимоисключающими. Если заданы оба свойства, ThumbImageSource
то свойство будет иметь приоритет.
Базовый код ползунка и разметка
Пример начинается с трех страниц, которые функционально идентичны, но реализуются разными способами. Первая страница использует только код C#, второй использует XAML с обработчиком событий в коде, а третий способен избежать обработчика событий с помощью привязки данных в XAML-файле.
Создание ползунка в коде
На странице "Базовый код ползунка" показано, как создать 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
}
};
}
}
Инициализировано Slider
Maximum
свойство 360. Обработчик ValueChanged
Slider
объекта использует Value
свойство slider
объекта для задания Rotation
свойства первого Label
и использует String.Format
метод со NewValue
свойством аргументов события для задания Text
свойства второго Label
. Эти два подхода для получения текущего Slider
значения являются взаимозаменяемыми.
Ниже приведена программа, запущенная на устройствах iOS и Android:
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
и свойство второго Label
Label
со 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 дискретных значений. Если задано Slider
Minimum
значение 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. Если разница между Maximum
свойствами и Minimum
свойствами составляет 10 или больше, то StepFrequency
имеет значение 1, а Value
свойство имеет целочисленные значения.
Решение StepSlider
Более универсальный StepSlider
обсуждается в главе 27. Пользовательские отрисовщики книги " Создание мобильных приложений с Xamarin.Formsпомощью . Аналогично, StepSlider
Slider
но добавляет Steps
свойство для указания количества значений между Minimum
и Maximum
.
Ползунки для выбора цвета
Последние две страницы в примере используют три 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:
Привязка ползунка к 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
По мере управления BoxView
Label
элементами элементы обновляются из ViewModel:
Компонент StringFormat
расширения разметки Binding
задается для формата "F2" для отображения двух десятичных разрядов. (Форматирование строк в привязках данных рассматривается в статье Форматирование строк.) Однако версия программы UWP ограничена значениями 0, 0.1, 0.2, ... 0.9 и 1.0. Это прямой результат реализации UWP Slider
, как описано выше в разделе "Различия в реализации платформы".