Xamarin.Forms Deslizador

Ejemplo de descarga Descarga del ejemplo

Use un control deslizante para seleccionar entre un intervalo de valores continuos.

es una barra horizontal que el usuario puede manipular para Xamarin.FormsSlider seleccionar un valor de un double intervalo continuo.

define Slider tres propiedades de tipo double :

Las tres propiedades están copiadas por BindableProperty objetos . La propiedad tiene un modo de enlace predeterminado de , lo que significa que es adecuado como origen de enlace en una aplicación que usa la arquitectura ValueBindingMode.TwoWayValue

Advertencia

Internamente, Slider garantiza que es menor que MinimumMaximum . Si Minimum o se establecen para que no sea menor que , se produce una MaximumMinimumMaximum excepción. Consulte la sección Precauciones a continuación para obtener más información sobre cómo establecer las propiedades y .

SliderCoerce la propiedad para que esté entre y , ambos ValueMinimumMaximum incluidos. Si la Minimum propiedad se establece en un valor mayor que la propiedad , establece la propiedad en ValueSliderValueMinimum . De forma similar, si se establece en un valor menor que , establece MaximumValue la propiedad en SliderValueMaximum .

Slider define un evento que se desencadena cuando cambia, ya sea mediante la manipulación por parte del usuario de ValueChanged o cuando el programa establece la propiedad ValueSliderValue directamente. También ValueChanged se desencadena un evento cuando la propiedad se Value coerci como se describe en el párrafo anterior.

El objeto que acompaña al evento tiene dos propiedades, ambas de tipo ValueChangedEventArgsValueChanged : Xamarin_Forms doubleValueChangedEventArgs _ValueChangedEventArgs_OldValue" data-linktype="absolute-path">y Xamarin_Forms OldValueValueChanged _ValueChangedEventArgs_NewValue" data-linktype="absolute-path">NewValue . En el momento en que se desencadena el evento, el valor de NewValue es el mismo que la propiedad del objeto ValueSlider .

Slider también define DragStarted los eventos y , que se DragCompleted desencadenan al principio y al final de la acción de arrastre. A diferencia ValueChanged del evento , los eventos y solo se DragStartedDragCompleted desencadenan mediante la manipulación del usuario de Slider . Cuando se DragStarted produce el evento, DragStartedCommand se ejecuta , de tipo ICommand . De forma similar, cuando se produce el evento, se ejecuta DragCompleted , de tipo DragCompletedCommandICommand .

Advertencia

No use opciones de diseño horizontal sin restricciones Center de , o con StartEndSlider . Tanto en Android como en UWP, se contrae en una barra de longitud cero y, en Slider iOS, la barra es muy corta. Mantenga el valor HorizontalOptions predeterminado de y no use un ancho de al colocar en un FillAutoSliderGrid diseño.

también Slider define varias propiedades que afectan a su apariencia:

Nota:

Las ThumbColor propiedades y son ThumbImageSource mutuamente excluyentes. Si se establecen ambas propiedades, la ThumbImageSource propiedad tendrá prioridad.

Código y marcado del control deslizante básico

El ejemplo SliderDemos comienza con tres páginas que son funcionalmente idénticas, pero que se implementan de maneras diferentes. La primera página solo usa código C#, la segunda usa XAML con un controlador de eventos en el código y la tercera puede evitar el controlador de eventos mediante el enlace de datos en el archivo XAML.

Crear un control deslizante en el código

La página Código del control deslizante básico del ejemplo SliderDemos muestra cómo crear un objeto y dos objetos en el código:

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

se Slider inicializa para tener una propiedad de Maximum 360. El controlador de utiliza la propiedad del objeto para establecer la propiedad del primero y usa el método con la propiedad de los ValueChangedSliderValuesliderRotationLabelString.FormatNewValue argumentos TextLabel de evento para establecer la propiedad del segundo . Estos dos enfoques para obtener el valor actual de son Slider intercambiables.

Este es el programa que se ejecuta en dispositivos iOS y Android:

Código deslizante básico Código deslizante

El segundo Label muestra el texto "(uninitialized)" hasta que se manipula , lo que hace que se desenlome Slider el primer ValueChanged evento. Observe que el número de posiciones decimales que se muestran es diferente para cada plataforma. Estas diferencias están relacionadas con las implementaciones de plataforma de y se de abordan más adelante en este artículo en la sección Diferencias de Slider implementación de la Slider.

Crear un control deslizante en XAML

La página XAML del control deslizante básico es funcionalmente la misma que el código deslizante básico, pero se implementa principalmente en 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>

El archivo de código subyacente contiene el controlador del ValueChanged evento:

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

También es posible que el controlador de eventos obtenga el que está activar Slider el evento a través del argumento sender . La Value propiedad contiene el valor actual:

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

Si al objeto se le asigna un nombre en el archivo XAML con un atributo Slider (por ejemplo, "slider"), el controlador de eventos podría hacer referencia x:Name directamente a ese objeto:

double value = slider.Value;

Enlace de datos del control deslizante

La página Enlaces deslizantes básicos muestra cómo escribir un programa casi equivalente que elimine el controlador de eventos mediante el enlace de datos:

<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 propiedad del primero está enlazada a la propiedad de , al igual que la propiedad Rotation del segundo con una LabelValueSliderTextLabelStringFormat especificación . La página Enlaces deslizantes básicos funciona de forma ligeramente diferente a las dos páginas anteriores: cuando la página aparece por primera vez, la segunda muestra la cadena de texto con el valor . Esta es una ventaja de usar el enlace de datos. Para mostrar texto sin enlace de datos, tendría que inicializar específicamente la propiedad de o simular una activación del evento llamando al controlador de eventos desde el TextLabel constructor de ValueChanged clase.

Precauciones

El valor de la Minimum propiedad siempre debe ser menor que el valor de la propiedad Maximum . El siguiente fragmento de código hace que Slider el elemento cause una excepción:

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

El compilador de C# genera código que establece estas dos propiedades en secuencia y, cuando la propiedad se establece en 10, es mayor que el Minimum valor Maximum predeterminado de 1. Puede evitar la excepción en este caso estableciendo primero Maximum la propiedad :

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

Establecer Maximum en 20 no es un problema porque es mayor que el valor Minimum predeterminado de 0. Cuando Minimum se establece , el valor es menor que el valor de Maximum 20.

Existe el mismo problema en XAML. Establezca las propiedades en un orden que garantice que Maximum siempre sea mayor que Minimum :

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

Puede establecer los valores y en números negativos, pero solo en un orden en el que Minimum siempre sea menor que MaximumMinimumMaximum :

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

La Value propiedad siempre es mayor o igual que el valor y menor o igual que MinimumMaximum . Si se establece en un valor fuera de ese intervalo, el valor se volverá a establecer dentro del intervalo, pero no se producirá Value ninguna excepción. Por ejemplo, este código no producirá una excepción:

Slider slider = new Slider
{
    Value = 10
};

En su lugar, Value la propiedad se coaccionó al Maximum valor de 1.

Este es un fragmento de código mostrado anteriormente:

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

Cuando Minimum se establece en 10, también se establece en Value 10.

Si se ha adjuntado un controlador de eventos en el momento en que la propiedad está coerciada a algo distinto de su valor predeterminado de 0, se desencadena ValueChangedValue un ValueChanged evento. Este es un fragmento de código XAML:

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

Cuando Minimum se establece en 10, también se establece en Value 10 y se ValueChanged desencadena el evento. Esto puede ocurrir antes de que se haya construido el resto de la página y el controlador podría intentar hacer referencia a otros elementos de la página que aún no se han creado. Es posible que quiera agregar código al controlador que comprueba ValueChanged los valores de otros elementos de la null página. O bien, puede establecer el controlador ValueChanged de eventos una vez Slider inicializados los valores.

Diferencias de implementación de plataforma

Las capturas de pantalla mostradas anteriormente muestran el valor de Slider con un número diferente de separadores decimales. Esto se relaciona con cómo Slider se implementa en las plataformas Android y UWP.

Implementación de Android

La implementación de Slider Android de se basa en Android y siempre establece la propiedad en SeekBarMax 1000. Esto significa que Slider en Android solo tiene 1001 valores discretos. Si establece para que tenga un de 0 y un de 5000, a medida que se manipula , la propiedad tiene valores SliderMinimum de MaximumSliderValue 0, 5, 10, 15, etc.

Implementación de UWP

La implementación de UWP Slider de se basa en el control de UWP. Slider La propiedad de UWP se establece en la diferencia de las propiedades y dividida StepFrequencySlider entre MaximumMinimum 10, pero no mayor que 1.

Por ejemplo, para el intervalo predeterminado de 0 a 1, la StepFrequency propiedad se establece en 0,1. A medida que se manipula , la propiedad está restringida a SliderValue 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 y 1.0. (Esto es evidente en la última página del ejemplo SliderDemos). Cuando la diferencia entre las propiedades y es 10 o superior, se establece en 1 y la MaximumMinimum propiedad tiene valores StepFrequencyValue enteros.

La solución StepSlider

En el capítulo StepSlider 27 se trata un tema StepSlider del libro Creating Mobile Apps with . es StepSlider similar a pero agrega una propiedad para especificar el número de valores entre y SliderStepsMinimumMaximum .

Controles deslizantes para la selección de colores

Las dos últimas páginas del ejemplo SliderDemos usan tres instancias para la selección de colores. La primera página controla todas las interacciones del archivo de código subyacente, mientras que la segunda página muestra cómo usar el enlace de datos con viewModel.

Control de controles deslizantes en el archivo de código subyacente

La página Controles deslizantes de color RGB crea una instancia de para mostrar un color, tres instancias para seleccionar los componentes rojo, verde y azul del color y tres elementos para mostrar esos valores de SliderLabel color:

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

Proporciona Style a los tres elementos un intervalo de Slider 0 a 255. Los Slider elementos comparten el ValueChanged mismo controlador, que se implementa en el archivo de código subyacente:

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 primera sección establece la propiedad de una de las instancias en una cadena de texto corto que indica Text el valor de en LabelSlider hexadecimal. A continuación, Slider se accede a las tres instancias para crear un valor a partir de los componentes Color RGB:

Controles deslizantes de

Enlazar el control deslizante a un modelo de vista

La página Controles deslizantes de color de HSL muestra cómo usar viewModel para realizar los cálculos usados para crear un valor a partir de valores de matiz, saturación y luminosidad. Al igual que todos los ViewModel, la clase implementa la interfaz y activa un evento cada vez que HSLColorViewModel cambia una de las INotifyPropertyChangedPropertyChanged propiedades:

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 y la INotifyPropertyChanged interfaz se de abordan en el artículo INotifyPropertyChanged.

El archivo HslColorSlidersPage.xaml crea una instancia de y la establece en la propiedad de la BindingContext página. Esto permite que todos los elementos del archivo XAML se enlacen a las propiedades de 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>

A medida Slider que se manipulan los elementos , BoxView los elementos y se actualizan desde Label ViewModel:

Controles deslizantes de color

El StringFormat componente de la extensión de marcado se establece para que un formato de Binding "F2" muestre dos posiciones decimales. (El formato de cadena en los enlaces de datos se describe en el artículo Formato de cadena). Sin embargo, la versión de UWP del programa se limita a los valores de 0, 0.1, 0.2, ... 0,9 y 1,0. Se trata de un resultado directo de la implementación de UWP como se describió anteriormente Slider en la sección Slider