Xamarin.Forms Controllo Slider
Usare un dispositivo di scorrimento per la selezione da un intervallo di valori continui.
Xamarin.FormsSlider
è una barra orizzontale che può essere modificata dall'utente per selezionare un double
valore da un intervallo continuo.
Definisce Slider
tre proprietà di tipo double
:
Minimum
è il valore minimo dell'intervallo, con un valore predefinito pari a 0.Maximum
è il valore massimo dell'intervallo, con un valore predefinito pari a 1.Value
è il valore del dispositivo di scorrimento, che può variare traMinimum
eMaximum
e ha un valore predefinito pari a 0.
Tutte e tre le proprietà sono supportate da BindableProperty
oggetti . La Value
proprietà ha una modalità di associazione predefinita di BindingMode.TwoWay
, il che significa che è adatto come origine di associazione in un'applicazione che usa l'architettura Model-View-ViewModel (MVVM).
Avviso
Internamente, garantisce Slider
che Minimum
sia minore di Maximum
. Se Minimum
o Maximum
sono mai impostati in modo che Minimum
non sia minore di Maximum
, viene generata un'eccezione. Per altre informazioni sull'impostazione delle proprietà eMaximum
, vedere la sezione Precauzioni di seguito.Minimum
La Slider
proprietà viene impostata Value
in modo che sia compresa tra Minimum
e Maximum
, inclusiva. Se la Minimum
proprietà è impostata su un valore maggiore della Value
proprietà , la Slider
Value
proprietà viene impostata su Minimum
. Analogamente, se Maximum
è impostato su un valore minore di Value
, Slider
la Value
proprietà viene impostata su Maximum
.
Slider
definisce un ValueChanged
evento generato quando cambia Value
, tramite la manipolazione dell'utente di Slider
o quando il programma imposta direttamente la Value
proprietà. Un ValueChanged
evento viene generato anche quando la Value
proprietà è forzata come descritto nel paragrafo precedente.
L'oggetto ValueChangedEventArgs
che accompagna l'evento ValueChanged
ha due proprietà, entrambe di tipo double
: OldValue
e NewValue
. Al momento della generazione dell'evento, il valore di NewValue
è uguale alla Value
proprietà dell'oggetto Slider
.
Slider
definisce DragStarted
inoltre gli eventi e DragCompleted
generati all'inizio e alla fine dell'azione di trascinamento. A differenza dell'evento ValueChanged
, gli DragStarted
eventi e DragCompleted
vengono generati solo tramite la Slider
manipolazione dell'utente di . Quando viene generato l'evento DragStarted
, DragStartedCommand
di tipo ICommand
, viene eseguito . Analogamente, quando viene generato l'evento DragCompleted
, DragCompletedCommand
di tipo ICommand
, viene eseguito .
Avviso
Non usare opzioni di layout orizzontale senza vincoli di Center
, Start
o End
con Slider
. Sia in Android che nella piattaforma UWP, il Slider
comprime su una barra di lunghezza zero e su iOS la barra è molto breve. Mantenere l'impostazione predefinita HorizontalOptions
di Fill
e non usare una larghezza di Auto
quando si inserisce Slider
un Grid
layout.
Definisce Slider
anche diverse proprietà che ne influiscono sull'aspetto:
MinimumTrackColor
è il colore della barra sul lato sinistro del pollice.MaximumTrackColor
è il colore della barra sul lato destro del pollice.ThumbColor
è il colore del pollice.ThumbImageSource
è l'immagine da usare per il pollice, di tipoImageSource
.
Nota
Le ThumbColor
proprietà e ThumbImageSource
si escludono a vicenda. Se vengono impostate entrambe le proprietà, la proprietà avrà la ThumbImageSource
precedenza.
Codice e markup di base del dispositivo di scorrimento
L'esempio inizia con tre pagine che sono funzionalmente identiche, ma vengono implementate in modi diversi. La prima pagina usa solo il codice C#, il secondo usa XAML con un gestore eventi nel codice e il terzo è in grado di evitare il gestore eventi usando il data binding nel file XAML.
Creazione di un dispositivo di scorrimento nel codice
La pagina Codice dispositivo di scorrimento di base mostra come creare un Slider
oggetto e due Label
oggetti nel codice:
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
}
};
}
}
L'oggetto Slider
viene inizializzato per avere una Maximum
proprietà di 360. Il ValueChanged
gestore dell'oggetto Slider
utilizza la Value
proprietà dell'oggetto slider
per impostare la Rotation
proprietà del primo Label
oggetto e utilizza il String.Format
metodo con la NewValue
proprietà degli argomenti dell'evento per impostare la Text
proprietà del secondo Label
. Questi due approcci per ottenere il valore corrente di Slider
sono intercambiabili.
Ecco il programma in esecuzione nei dispositivi iOS e Android:
Il secondo Label
visualizza il testo "(non inizializzato)" fino a quando l'oggetto Slider
non viene modificato, causando la generazione del primo ValueChanged
evento. Si noti che il numero di posizioni decimali visualizzate è diverso per ogni piattaforma. Queste differenze sono correlate alle implementazioni della piattaforma di Slider
e sono descritte più avanti in questo articolo nella sezione Differenze di implementazione della piattaforma.
Creazione di un dispositivo di scorrimento in XAML
La pagina XAML Del dispositivo di scorrimento di base è funzionalmente identica a Quella del dispositivo di scorrimento di base, ma implementata principalmente in 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>
Il file code-behind contiene il gestore per l'evento 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);
}
}
È anche possibile che il gestore eventi ottenga l'oggetto Slider
che genera l'evento tramite l'argomento sender
. La Value
proprietà contiene il valore corrente:
double value = ((Slider)sender).Value;
Se all'oggetto Slider
è stato assegnato un nome nel file XAML con un x:Name
attributo ,ad esempio "slider", il gestore eventi potrebbe fare riferimento direttamente a tale oggetto:
double value = slider.Value;
Data binding del dispositivo di scorrimento
Nella pagina Binding di dispositivo di scorrimento di base viene illustrato come scrivere un programma quasi equivalente che elimina il Value
gestore eventi tramite data binding:
<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>
La Rotation
proprietà del primo Label
è associata alla Value
proprietà di Slider
, così come è la Text
proprietà del secondo Label
con una StringFormat
specifica. La pagina Basic Slider Bindings funziona in modo leggermente diverso dalle due pagine precedenti: quando viene visualizzata la prima pagina, la seconda Label
visualizza la stringa di testo con il valore . Questo è un vantaggio dell'uso del data binding. Per visualizzare testo senza data binding, è necessario inizializzare in modo specifico la Text
proprietà dell'oggetto Label
o simulare una generazione dell'evento ValueChanged
chiamando il gestore eventi dal costruttore della classe.
Precauzioni
Il valore della Minimum
proprietà deve essere sempre minore del valore della Maximum
proprietà. Il frammento di codice seguente fa sì che generi un'eccezione Slider
:
// Throws an exception!
Slider slider = new Slider
{
Minimum = 10,
Maximum = 20
};
Il compilatore C# genera codice che imposta queste due proprietà in sequenza e quando la Minimum
proprietà è impostata su 10, è maggiore del valore predefinito Maximum
1. È possibile evitare l'eccezione in questo caso impostando prima la Maximum
proprietà :
Slider slider = new Slider
{
Maximum = 20,
Minimum = 10
};
L'impostazione Maximum
su 20 non è un problema perché è maggiore del valore predefinito Minimum
0. Quando Minimum
è impostato, il valore è minore del Maximum
valore di 20.
Lo stesso problema esiste in XAML. Impostare le proprietà in un ordine che garantisce che Maximum
sia sempre maggiore di Minimum
:
<Slider Maximum="20"
Minimum="10" ... />
È possibile impostare i Minimum
valori e Maximum
su numeri negativi, ma solo in un ordine in cui Minimum
è sempre minore di Maximum
:
<Slider Minimum="-20"
Maximum="-10" ... />
La Value
proprietà è sempre maggiore o uguale al Minimum
valore e minore o uguale a Maximum
. Se Value
è impostato su un valore esterno a tale intervallo, il valore verrà costretto a trovarsi all'interno dell'intervallo, ma non viene generata alcuna eccezione. Ad esempio, questo codice non genererà un'eccezione:
Slider slider = new Slider
{
Value = 10
};
La proprietà viene invece Value
associata al Maximum
valore 1.
Ecco un frammento di codice illustrato sopra:
Slider slider = new Slider
{
Maximum = 20,
Minimum = 10
};
Quando Minimum
è impostato su 10, Value
viene impostato anche su 10.
Se un ValueChanged
gestore eventi è stato associato al momento in cui la Value
proprietà è associata a un valore diverso dal valore predefinito 0, viene generato un ValueChanged
evento. Ecco un frammento di codice XAML:
<Slider ValueChanged="OnSliderValueChanged"
Maximum="20"
Minimum="10" />
Quando Minimum
è impostato su 10, Value
viene impostato anche su 10 e l'evento ValueChanged
viene generato. Questo problema può verificarsi prima che il resto della pagina sia stato costruito e il gestore potrebbe tentare di fare riferimento ad altri elementi nella pagina che non sono ancora stati creati. Potrebbe essere necessario aggiungere codice al ValueChanged
gestore che verifica la presenza null
di valori di altri elementi nella pagina. In alternativa, è possibile impostare il gestore eventi dopo l'inizializzazione ValueChanged
dei Slider
valori.
Differenze di implementazione della piattaforma
Gli screenshot mostrati in precedenza il valore di Slider
con un numero diverso di punti decimali. Questo riguarda il Slider
modo in cui viene implementato nelle piattaforme Android e UWP.
Implementazione di Android
L'implementazione android di Slider
è basata su Android SeekBar
e imposta sempre la Max
proprietà su 1000. Ciò significa che in Slider
Android sono presenti solo 1.001 valori discreti. Se si imposta l'oggetto Slider
su su 0 e su Maximum
5000, come Slider
viene modificato, la Value
proprietà ha valori pari a Minimum
0, 5, 10, 15 e così via.
Implementazione della piattaforma UWP
L'implementazione UWP di Slider
è basata sul controllo UWP Slider
. La StepFrequency
proprietà della piattaforma UWP Slider
è impostata sulla differenza tra le Maximum
proprietà e Minimum
diviso per 10, ma non maggiore di 1.
Ad esempio, per l'intervallo predefinito da 0 a 1, la StepFrequency
proprietà è impostata su 0,1. Slider
Poiché viene modificato, la Value
proprietà è limitata a 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 e 1.0. Quando la differenza tra le Maximum
proprietà e Minimum
è 10 o superiore, StepFrequency
viene impostata su 1 e la Value
proprietà ha valori integrali.
Soluzione StepSlider
Il capitolo 27 illustra una maggiore versatilitàStepSlider
. Renderer personalizzati del libro Creazione di app per dispositivi mobili con Xamarin.Forms. è StepSlider
simile a Slider
ma aggiunge una Steps
proprietà per specificare il numero di valori tra Minimum
e Maximum
.
Dispositivi di scorrimento per la selezione dei colori
Le due pagine finali dell'esempio usano entrambe tre Slider
istanze per la selezione dei colori. La prima pagina gestisce tutte le interazioni nel file code-behind, mentre la seconda pagina mostra come usare il data binding con viewModel.
Gestione dei dispositivi di scorrimento nel file code-behind
La pagina Dispositivi di scorrimento colori RGB crea un'istanza di per BoxView
visualizzare un colore, tre Slider
istanze per selezionare i componenti rosso, verde e blu del colore e tre Label
elementi per la visualizzazione di tali valori di colore:
<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>
Un Style
oggetto fornisce a tutti e tre Slider
gli elementi un intervallo compreso tra 0 e 255. Gli Slider
elementi condividono lo stesso ValueChanged
gestore, implementato nel file code-behind:
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);
}
}
La prima sezione imposta la Text
proprietà di una delle Label
istanze su una stringa di testo breve che indica il valore dell'oggetto Slider
in formato esadecimale. È quindi possibile accedere a tutte e tre Slider
le istanze per creare un Color
valore dai componenti RGB:
Associazione del dispositivo di scorrimento a un viewModel
La pagina HSL Color Sliders (Dispositivi di scorrimento colori HSL) mostra come usare un viewModel per eseguire i calcoli usati per creare un Color
valore dai valori di tonalità, saturazione e luminosità. Come tutti i ViewModel, la HSLColorViewModel
classe implementa l'interfaccia INotifyPropertyChanged
e genera un PropertyChanged
evento ogni volta che una delle proprietà cambia:
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 e l'interfaccia INotifyPropertyChanged
sono descritti nell'articolo Data Binding.
Il file HslColorSlidersPage.xaml crea un'istanza di HslColorViewModel
e lo imposta sulla proprietà della BindingContext
pagina. In questo modo tutti gli elementi del file XAML possono essere associati alle proprietà in 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>
Man mano che gli Slider
elementi vengono modificati, gli BoxView
elementi e Label
vengono aggiornati da ViewModel:
Il StringFormat
componente dell'estensione Binding
di markup è impostato per un formato "F2" per visualizzare due posizioni decimali. La formattazione delle stringhe nei data binding è descritta nell'articolo Formattazione di stringhe. Tuttavia, la versione UWP del programma è limitata ai valori 0, 0.1, 0.2, ... 0.9 e 1.0. Si tratta di un risultato diretto dell'implementazione della piattaforma UWP Slider
, come descritto in precedenza nella sezione Differenze di implementazione della piattaforma.