Control de incremento

.NET Multi-Platform App UI (.NET MAUI) Stepper permite seleccionar un valor numérico de un rango de valores. Consta de dos botones etiquetados con signos menos y más. El usuario puede manipular estos botones para seleccionar incrementalmente un valor double de un rango de valores.

Stepper define dos propiedades de tipo double:

  • Increment es la cantidad por la que se cambia el valor seleccionado, con un valor predeterminado de 1.
  • Minimum es el valor mínimo del rango, con un valor predeterminado de 0.
  • Maximum es el valor máximo del rango, con un valor predeterminado de 100.
  • Value es el valor del control de incremento, que puede oscilar entre Minimum y Maximum, y tiene un valor predeterminado de 0.

Todos estos objetos están respaldados por objetos BindableProperty. La propiedad Value tiene un modo de enlace predeterminado de BindingMode.TwoWay, lo que significa que es adecuado como origen de enlace en una aplicación que usa el patrón Modelo-Vista-Modelo de vista (MVVM).

Stepper fuerza la propiedad Value para que esté entre Minimum y Maximum, ambos inclusive. Si la propiedad Minimum se establece en un valor mayor que la propiedad Value, Stepper establece la propiedad Value en Minimum. Del mismo modo, si Maximum se establece en un valor menor que Value, Stepper establece la propiedad Value en Maximum. Internamente, Stepper garantiza que Maximum sea menor que Minimum. Si Minimum o Maximum se establecen alguna vez para que Maximum no sea menor que Minimum, se genera una excepción. Para más información sobre cómo establecer las propiedades Minimum y Maximum, consulta Precauciones.

Stepper define un evento ValueChanged que se genera cuando Value cambia, ya sea mediante la manipulación del usuario de Stepper o cuando la aplicación establece la propiedad Value directamente. También se genera un evento ValueChanged cuando se fuerza la propiedad Value, tal como se ha descrito antes. El objeto ValueChangedEventArgs que acompaña al evento ValueChanged tiene OldValue y NewValue, de tipo double. En el momento en que se genera el evento, el valor de NewValue es el mismo que la propiedad Value del objeto Stepper.

Creación de un elemento Stepper

En el ejemplo siguiente se muestra cómo se crea un elemento Stepper con dos objetos Label:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="StepperDemo.BasicStepperXAMLPage"
             Title="Basic Stepper XAML">
    <StackLayout Margin="20">
        <Label x:Name="_rotatingLabel"
               Text="ROTATING TEXT"
               FontSize="18"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
        <Stepper Maximum="360"
                 Increment="30"
                 HorizontalOptions="Center"
                 ValueChanged="OnStepperValueChanged" />
        <Label x:Name="_displayLabel"
               Text="(uninitialized)"
               HorizontalOptions="Center"
               VerticalOptions="Center" />        
    </StackLayout>
</ContentPage>

En este ejemplo, se inicializa Stepper para que tenga una propiedad Maximum de 360 y una propiedad Increment de 30. Si se manipula Stepper, el valor seleccionado cambia incrementalmente entre Minimum y Maximum en función del valor de la propiedad Increment. El segundo objeto Label muestra el texto "(sin inicializar)" hasta que se manipule Stepper, lo que hace que se genere el primer evento ValueChanged.

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

public partial class BasicStepperXAMLPage : ContentPage
{
    public BasicStepperXAMLPage()
    {
        InitializeComponent();
    }

    void OnStepperValueChanged(object sender, ValueChangedEventArgs e)
    {
        double value = e.NewValue;
        _rotatingLabel.Rotation = value;
        _displayLabel.Text = string.Format("The Stepper value is {0}", value);
    }
}

El controlador ValueChanged de Stepper utiliza la propiedad Value del objeto stepper para establecer la propiedad Rotation del primer objeto Label, y usa el método string.Format con la propiedad NewValue de los argumentos del evento para establecer la propiedad Text del segundo objeto Label:

.NET MAUI Stepper screenshot.

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

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

Si el objeto Stepper recibiera un nombre en el archivo XAML con un atributo x:Name (por ejemplo, "stepper"), el controlador de eventos podría hacer referencia directamente a ese objeto:

double value = stepper.Value;

El código equivalente en C# para crear un objeto Stepper es:

Stepper stepper = new Stepper
{
    Maximum = 360,
    Increment = 30,
    HorizontalOptions = LayoutOptions.Center
};
stepper.ValueChanged += (sender, e) =>
{
    rotationLabel.Rotation = stepper.Value;
    displayLabel.Text = string.Format("The Stepper value is {0}", e.NewValue);
};

Enlace de datos de Stepper

El controlador de eventos ValueChanged se puede eliminar mediante el enlace de datos para responder al cambio de valor de Stepper:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="StepperDemo.BasicStepperBindingsPage"
             Title="Basic Stepper Bindings">
    <StackLayout Margin="20">
        <Label Text="ROTATING TEXT"
               Rotation="{Binding Source={x:Reference _stepper}, Path=Value}"
               FontSize="18"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
        <Stepper x:Name="_stepper"
                 Maximum="360"
                 Increment="30"
                 HorizontalOptions="Center" />
        <Label Text="{Binding Source={x:Reference _stepper}, Path=Value, StringFormat='The Stepper value is {0:F0}'}"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

En este ejemplo, la propiedad Rotation del primer objeto Label está enlazada a la propiedad Value de Stepper, ya que es la propiedad Text del segundo objeto Label con una especificación StringFormat. Cuando aparezca la página por primera vez, el segundo objeto Label muestra la cadena de texto con el valor. Para mostrar texto sin enlace de datos, tendrás que inicializar específicamente la propiedad Text de Label o simular una activación del evento ValueChanged llamando al controlador de eventos desde el constructor de clase.

Precauciones

El valor de la propiedad Minimum debe ser menor que el valor de la propiedad Maximum. En el siguiente ejemplo de código, Stepper genera una excepción:

// Throws an exception!
Stepper stepper = new Stepper
{
    Minimum = 180,
    Maximum = 360
};

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

Stepper stepper = new Stepper
{
    Maximum = 360,
    Minimum = 180
};

En este ejemplo, establecer Maximum en 360 no es un problema porque es mayor que el valor predeterminado Minimum de 0. Cuando Minimum está establecido, el valor es menor que el valor Maximum de 360.

El mismo problema existe en XAML. Establece las propiedades en un orden que garantice que Maximum siempre sea mayor que Minimum:

<Stepper Maximum="360"
         Minimum="180" ... />

Luego, puedes establecer los valores Minimum y Maximum en números negativos, pero solo en un orden donde Minimum siempre sea menor que Maximum:

<Stepper Minimum="-360"
         Maximum="-180" ... />

La propiedad Value siempre es mayor o igual que el valor Minimum y menor o igual que Maximum. Si Value se establece en un valor fuera de ese intervalo, el valor será forzado a estar dentro del rango, pero no se genera ninguna excepción. Por ejemplo, este código no generará una excepción:

Stepper stepper = new Stepper
{
    Value = 180
};

En su lugar, la propiedad Value se convierte al valor Maximum de 100.

Un ejemplo anterior establecido Maximum en 360 y Minimum en 180:

Stepper stepper = new Stepper
{
    Maximum = 360,
    Minimum = 180
};

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

Si se ha asociado un controlador de eventos ValueChanged en el momento en que la propiedad Value está forzada a algo distinto de su valor predeterminado de 0, se genera un evento ValueChanged:

<Stepper ValueChanged="OnStepperValueChanged"
         Maximum="360"
         Minimum="180" />

Cuando Minimum se establece en 180, Value también se establece en 180 y se genera el evento ValueChanged. Esto puede suceder 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 desee agregar código al constructor ValueChanged que comprueba si hay valores null de otros elementos en la página. O bien, puedes establecer el controlador de eventos ValueChanged después de inicializar los valores Stepper.