Xamarin.Forms Běhoun
Pro výběr z rozsahu souvislých hodnot použijte posuvník.
Jedná se Xamarin.FormsSlider
o vodorovný pruh, se kterým může uživatel manipulovat a vybrat double
hodnotu z souvislého rozsahu.
Definuje Slider
tři vlastnosti typu double
:
Minimum
je minimum rozsahu s výchozí hodnotou 0.Maximum
je maximální rozsah s výchozí hodnotou 1.Value
je hodnota posuvníku, která může být v rozsahu meziMinimum
aMaximum
má výchozí hodnotu 0.
Všechny tři vlastnosti jsou podporovány BindableProperty
objekty. Vlastnost Value
má výchozí režim vazby BindingMode.TwoWay
, což znamená, že je vhodný jako zdroj vazby v aplikaci, která používá architekturu Model-View-ViewModel (MVVM).
Upozorňující
Interně zajišťuje Slider
, že je Minimum
menší než Maximum
. Pokud Minimum
nebo Maximum
jsou někdy nastaveny tak, aby Minimum
to nebylo menší než Maximum
, je vyvolána výjimka. Další informace o nastavení Minimum
a Maximum
vlastnostech najdete v části Preventivní opatření níže.
Value
Převede Slider
vlastnost tak, aby byla mezi Minimum
a Maximum
, včetně. Minimum
Pokud je vlastnost nastavena na hodnotu větší než Value
vlastnost, Slider
nastaví Value
vlastnost na Minimum
. Podobně pokud Maximum
je nastavena na hodnotu menší než Value
, pak Slider
nastaví Value
vlastnost na Maximum
.
Slider
ValueChanged
definuje událost, která se aktivuje při Value
změně, buď prostřednictvím manipulace Slider
s uživatelem nebo když program nastaví Value
vlastnost přímo. Událost ValueChanged
se aktivuje také v případě, že Value
je vlastnost vyřazena, jak je popsáno v předchozím odstavci.
Objekt ValueChangedEventArgs
, který doprovází ValueChanged
událost, má dvě vlastnosti, oba typy double
: OldValue
a NewValue
. V době, kdy se událost aktivuje, je hodnota NewValue
stejná jako Value
vlastnost objektu Slider
.
Slider
definuje DragStarted
a DragCompleted
události, které se aktivují na začátku a na konci akce přetažení. ValueChanged
Na rozdíl od události DragStarted
se události a DragCompleted
události aktivují pouze prostřednictvím manipulace s uživatelem Slider
. Když se DragStarted
událost aktivuje, DragStartedCommand
spustí se typ ICommand
, . Podobně, když se DragCompleted
událost aktivuje, DragCompletedCommand
spustí se typ ICommand
, .
Upozorňující
Nepoužívejte nekontrénované vodorovné možnosti Center
rozložení , Start
nebo End
s Slider
. Na Androidu i UPW se Slider
sbalí na pruh nulové délky a v iOSu je panel velmi krátký. Ponechte výchozí HorizontalOptions
nastavení Fill
a nepoužívejte šířku Auto
Grid
při vkládání Slider
do rozložení.
Definuje Slider
také několik vlastností, které ovlivňují jeho vzhled:
MinimumTrackColor
je barva pruhu na levé straně palce.MaximumTrackColor
je barva pruhu na pravé straně palce.ThumbColor
je barva palce.ThumbImageSource
je obrázek, který se má použít pro palec, typuImageSource
.
Poznámka:
Vlastnosti ThumbColor
se ThumbImageSource
vzájemně vylučují. Pokud jsou nastaveny obě vlastnosti, ThumbImageSource
bude mít tato vlastnost přednost.
Kód a kód základního posuvníku
Ukázka začíná třemi stránkami, které jsou funkčně identické, ale implementují se různými způsoby. První stránka používá pouze kód jazyka C#, druhý používá XAML s obslužnou rutinou události v kódu a třetí je schopen zabránit obslužné rutině události pomocí datové vazby v souboru XAML.
Vytvoření posuvníku v kódu
Stránka Kód základního posuvníku ukazuje vytvoření Slider
a dva Label
objekty v kódu:
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
}
};
}
}
Inicializuje Slider
se tak, aby měla Maximum
vlastnost 360. Obslužná rutina používá vlastnost objektu k nastavení Rotation
vlastnosti první Label
a používá String.Format
metodu s NewValue
vlastností argumentů události k nastavení Text
vlastnosti druhé Label
.slider
Value
Slider
ValueChanged
Tyto dva přístupy k získání aktuální hodnoty Slider
jsou zaměnitelné.
Tady je program spuštěný na zařízeních s iOSem a Androidem:
Label
Druhá zobrazí text "(neinicializovaný)", dokud Slider
nebude manipulován, což způsobí, že se aktivuje první ValueChanged
událost. Všimněte si, že počet zobrazených desetinných míst se pro každou platformu liší. Tyto rozdíly souvisejí s implementacemi platformy a jsou popsány Slider
dále v tomto článku v části Rozdíly v implementaci platformy.
Vytvoření posuvníku v XAML
Stránka XAML základního posuvníku je funkčně stejná jako základní kód posuvníku, ale implementovaná převážně v jazyce 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>
Soubor kódu obsahuje obslužnou rutinu ValueChanged
události:
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);
}
}
Je také možné, aby obslužná rutina události získala Slider
událost, která událost spouští prostřednictvím argumentu sender
. Vlastnost Value
obsahuje aktuální hodnotu:
double value = ((Slider)sender).Value;
Slider
Pokud byl objektu zadán název v souboru XAML s atributem x:Name
(například "slider"), může obslužná rutina události odkazovat přímo na tento objekt:
double value = slider.Value;
Datová vazba posuvníku
Stránka Vazby základních posuvníků ukazuje, jak napsat téměř ekvivalentní program, který eliminuje obslužnou rutinu Value
události pomocí datové vazby:
<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>
Vlastnost Rotation
prvního Label
je vázána na Value
vlastnost Slider
, jak je Text
vlastnost druhého Label
se StringFormat
specifikací. Stránka Vazby základních posuvníků funguje trochu jinak než na dvou předchozích stránkách: Při prvním zobrazení stránky se druhý Label
zobrazí textový řetězec s hodnotou. To je výhoda použití datové vazby. Chcete-li zobrazit text bez datové vazby, musíte konkrétně inicializovat Text
vlastnost Label
události nebo simulovat spuštění ValueChanged
události voláním obslužné rutiny události z konstruktoru třídy.
Opatření
Hodnota Minimum
vlastnosti musí být vždy menší než hodnota Maximum
vlastnosti. Následující fragment kódu způsobí Slider
vyvolání výjimky:
// Throws an exception!
Slider slider = new Slider
{
Minimum = 10,
Maximum = 20
};
Kompilátor jazyka C# vygeneruje kód, který nastaví tyto dvě vlastnosti v posloupnosti a když Minimum
je vlastnost nastavena na hodnotu 10, je větší než výchozí Maximum
hodnota 1. V tomto případě se můžete vyhnout výjimce tím, že Maximum
nejprve nastavíte vlastnost:
Slider slider = new Slider
{
Maximum = 20,
Minimum = 10
};
Nastavení Maximum
na hodnotu 20 není problém, protože je větší než výchozí Minimum
hodnota 0. Pokud Minimum
je tato hodnota nastavená, je menší než Maximum
hodnota 20.
Stejný problém existuje v XAML. Nastavte vlastnosti v pořadí, které zajišťuje, že Maximum
je vždy větší než Minimum
:
<Slider Maximum="20"
Minimum="10" ... />
Hodnoty a Maximum
hodnoty můžete nastavit Minimum
na záporná čísla, ale pouze v pořadí, ve kterém Minimum
je vždy menší než Maximum
:
<Slider Minimum="-20"
Maximum="-10" ... />
Vlastnost Value
je vždy větší nebo rovna hodnotě Minimum
a menší než nebo rovno Maximum
. Pokud Value
je nastavená hodnota mimo tuto oblast, bude hodnota vymýšlena tak, aby leží v rozsahu, ale nevyvolá se žádná výjimka. Tento kód například nevyvolá výjimku:
Slider slider = new Slider
{
Value = 10
};
Místo toho se Value
vlastnost převede na Maximum
hodnotu 1.
Tady je fragment kódu uvedený výše:
Slider slider = new Slider
{
Maximum = 20,
Minimum = 10
};
Pokud Minimum
je nastavená hodnota 10, je Value
také nastavena na hodnotu 10.
Pokud byla obslužná ValueChanged
rutina události připojena v době, kdy Value
je vlastnost vyřizována k něčemu jinému, než je jeho výchozí hodnota 0, ValueChanged
je událost aktivována. Tady je fragment kódu XAML:
<Slider ValueChanged="OnSliderValueChanged"
Maximum="20"
Minimum="10" />
Pokud Minimum
je nastavená hodnota 10, Value
nastaví se také hodnota 10 a ValueChanged
událost se aktivuje. K tomu může dojít před vytvořením zbytku stránky a obslužná rutina se může pokusit odkazovat na další prvky na stránce, které ještě nebyly vytvořeny. Do obslužné rutiny můžete přidat nějaký kód ValueChanged
, který kontroluje null
hodnoty jiných prvků na stránce. Nebo můžete obslužnou rutinu ValueChanged
události nastavit po Slider
inicializaci hodnot.
Rozdíly v implementaci platformy
Snímky obrazovky zobrazené dříve zobrazují hodnotu čísla Slider
s jiným počtem desetinných míst. To souvisí s tím, jak Slider
se implementuje na platformách Android a UPW.
Implementace Androidu
Implementace Androidu Slider
je založena na Androidu SeekBar
a vždy nastaví Max
vlastnost na 1 000. To znamená, že v Androidu Slider
je pouze 1 001 diskrétních hodnot. Pokud nastavíte Slider
hodnotu Minimum
0 a Maximum
5 000, pak při Slider
manipulaci Value
s vlastností jsou hodnoty 0, 5, 10, 15 atd.
Implementace UPW
Implementace UPW Slider
je založená na ovládacím prvku UPW Slider
. Vlastnost StepFrequency
UPW Slider
je nastavena na rozdíl a Maximum
Minimum
vlastnosti dělené 10, ale ne větší než 1.
Například pro výchozí rozsah 0 až 1 StepFrequency
je vlastnost nastavena na hodnotu 0,1. Slider
Při manipulaci Value
s vlastností je omezeno na 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 a 1.0. Pokud je rozdíl mezi Maximum
vlastnostmi Minimum
10 nebo větší, je nastaven StepFrequency
na hodnotu 1 a Value
vlastnost má celočíselné hodnoty.
Řešení StepSlider
Více všestrannější StepSlider
je popsáno v kapitole 27. Vlastní renderery knihy Vytváření mobilních aplikací s Xamarin.Forms. Je StepSlider
podobný, Slider
ale přidá Steps
vlastnost, která určuje počet hodnot mezi Minimum
a Maximum
.
Posuvníky pro výběr barev
Poslední dvě stránky v ukázce používají pro výběr barev tři Slider
instance. První stránka zpracovává všechny interakce v souboru kódu za kódem, zatímco druhá stránka ukazuje, jak používat datové vazby s modelem ViewModel.
Zpracování posuvníků v souboru s kódem
Stránka Posuvníky barev RGB vytvoří BoxView
instanci pro zobrazení barvy, tří Slider
instancí pro výběr červených, zelených a modrých součástí barvy a tří Label
prvků pro zobrazení těchto hodnot barev:
<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
poskytuje všechny tři Slider
prvky rozsah 0 až 255. Prvky Slider
sdílejí stejnou obslužnou ValueChanged
rutinu, která se implementuje v souboru kódu:
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);
}
}
První oddíl nastaví Text
vlastnost jedné z Label
instancí na krátký textový řetězec označující hodnotu Slider
v šestnáctkové soustavě. Pak se ke všem třem Slider
instancím přistupuje, aby se vytvořila Color
hodnota ze součástí RGB:
Vytvoření vazby posuvníku k modelu ViewModel
Na stránce Posuvníky barev HSL se dozvíte, jak pomocí modelu ViewModel provádět výpočty používané k vytvoření Color
hodnoty odstínu, sytosti a světelnosti. Stejně jako všechny ViewModels HSLColorViewModel
třída implementuje INotifyPropertyChanged
rozhraní a aktivuje PropertyChanged
událost pokaždé, když se změní jedna z vlastností:
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;
}
}
}
Modely ViewModel a INotifyPropertyChanged
rozhraní jsou popsány v článku Datové vazby.
Soubor HslColorSlidersPage.xaml vytvoří HslColorViewModel
instanci a nastaví ji na vlastnost stránky BindingContext
. To umožňuje všem prvkům v souboru XAML vytvořit vazbu na vlastnosti v 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
Při manipulaci BoxView
s prvky a Label
prvky se aktualizují z modelu ViewModel:
Komponenta StringFormat
Binding
rozšíření značek je nastavena pro formát "F2" pro zobrazení dvou desetinných míst. (Formátování řetězců v datových vazbách je popsáno v článku Formátování řetězců.) Verze programu UPW je však omezena na hodnoty 0, 0.1, 0.2, ... 0.9 a 1.0. Jedná se o přímý výsledek implementace UPW Slider
, jak je popsáno výše v části Rozdíly v implementaci platformy.