Elemento RadioButton de Xamarin.Forms

El elemento RadioButton de Xamarin.Forms es un tipo de botón que permite a los usuarios seleccionar una opción de un conjunto. Cada opción aparece representada por un botón de radio y los usuarios solo pueden seleccionar un único botón de radio en un grupo de botones de radio. De forma predeterminada, cada RadioButton muestra texto:

Captura de pantalla de RadioButtons predeterminados

Pero en algunas plataformas, un RadioButton puede mostrar una clase View, y en todas las plataformas se puede redefinir la apariencia de cada RadioButton con ControlTemplate:

Captura de pantalla de RadioButtons redefinidos

El control RadioButton define las propiedades siguientes:

  • Content, de tipo object, que define el objeto string o View que va a mostrar RadioButton.
  • IsChecked, de tipo bool, que define si RadioButton está activado. Esta propiedad usa un enlace TwoWay y tiene un valor predeterminado de false.
  • GroupName, de tipo string, que define el nombre que especifica qué controles de RadioButton son mutuamente excluyentes. Esta propiedad tiene un valor predeterminado de null.
  • Value, de tipo object, que define un valor único opcional asociado a RadioButton.
  • BorderColor, de tipo Color, que define el color del trazo del borde.
  • BorderWidth, de tipo double, que define el ancho del borde de RadioButton.
  • CharacterSpacing, de tipo double, que define el espaciado entre caracteres de cualquier texto mostrado.
  • CornerRadius, de tipo int, que define el radio de esquina de RadioButton.
  • FontAttributes, de tipo FontAttributes, que determina el estilo del texto.
  • FontFamily, de tipo string, que define la familia de fuentes.
  • FontSize, de tipo double, que define el tamaño de fuente.
  • TextColor, de tipo Color, que define el color de cualquier texto mostrado.
  • TextTransform, de tipo TextTransform, que define el uso de mayúsculas y minúsculas de cualquier texto mostrado.

Estas propiedades están respaldadas por objetos BindableProperty, lo que significa que pueden ser destinos de los enlaces de datos, y que se les puede aplicar un estilo.

El control RadioButton también define un evento CheckedChanged que se desencadena cuando cambia la propiedad IsChecked, ya sea con la manipulación mediante programación o por parte del usuario. El objeto CheckedChangedEventArgs que acompaña al evento CheckedChanged tiene una sola propiedad llamada Value, de tipo bool. Cuando se desencadena el evento, el valor de la propiedad CheckedChangedEventArgs.Value se establece en el nuevo valor de la propiedad IsChecked.

RadioButton La agrupación se puede administrar mediante la clase RadioButtonGroup, que define las siguientes propiedades adjuntas:

  • GroupName, de tipo string, que define el nombre del grupo de los objetos RadioButton de un elemento Layout<View>.
  • SelectedValue, de tipo object, que representa el valor del objeto RadioButton seleccionado dentro de un grupo de un elemento Layout<View>. Esta propiedad adjunta usa un enlace TwoWay de forma predeterminada.

Para más información sobre la propiedad adjunta GroupName consulta Agrupar RadioButtons. Para obtener más información sobre la propiedad adjunta SelectedValue, consulta Responder a los cambios de estado de RadioButton.

Crear radioButtons

La apariencia de un objeto RadioButton se define mediante el tipo de datos asignados a la propiedad RadioButton.Content:

  • Cuando se asigna a la propiedad RadioButton.Content un elemento string, se mostrará en cada plataforma, alineada horizontalmente junto al círculo del botón de radio.
  • Cuando se asigna al elemento RadioButton.Content un elemento View, se mostrará en las plataformas compatibles (iOS, UWP), mientras que las plataformas no compatibles revertirán a una representación de cadena del objeto View (Android). En ambos casos, el contenido se muestra alineado horizontalmente junto al círculo del botón de radio.
  • Cuando se aplica ControlTemplate a RadioButton, se puede asignar View a la propiedad RadioButton.Content en todas las plataformas. Para más información, consulta Redefinir la apariencia de RadioButton.

Mostrar contenido basado en cadenas

RadioButton muestra texto cuando se asigna a la propiedad Content un elemento string:

<StackLayout>
    <Label Text="What's your favorite animal?" />
    <RadioButton Content="Cat" />
    <RadioButton Content="Dog" />
    <RadioButton Content="Elephant" />
    <RadioButton Content="Monkey"
                 IsChecked="true" />
</StackLayout>

En este ejemplo, los objetos RadioButton se agrupan implícitamente dentro del mismo contenedor primario. Este código XAML da como resultado la apariencia que se muestra en las siguientes capturas de pantalla:

Captura de pantalla de RadioButtons basados en texto

Mostrar contenido arbitrario

En iOS y UWP, un elemento RadioButton puede mostrar contenido arbitrario cuando a la propiedad Content se le asigna un elemento View:

<StackLayout>
    <Label Text="What's your favorite animal?" />
    <RadioButton>
        <RadioButton.Content>
            <Image Source="cat.png" />
        </RadioButton.Content>
    </RadioButton>
    <RadioButton>
        <RadioButton.Content>
            <Image Source="dog.png" />
        </RadioButton.Content>
    </RadioButton>
    <RadioButton>
        <RadioButton.Content>
            <Image Source="elephant.png" />
        </RadioButton.Content>
    </RadioButton>
    <RadioButton>
        <RadioButton.Content>
            <Image Source="monkey.png" />
        </RadioButton.Content>
    </RadioButton>
</StackLayout>

En este ejemplo, los objetos RadioButton se agrupan implícitamente dentro del mismo contenedor primario. Este código XAML da como resultado la apariencia que se muestra en las siguientes capturas de pantalla:

Captura de pantalla de RadioButtons basados en vistas

En Android, los objetos RadioButton mostrarán una representación basada en cadenas del objeto View que se ha establecido como contenido:

Captura de pantalla de RadioButton basado en vistas en Android

Nota:

Cuando se aplica ControlTemplate a RadioButton, se puede asignar View a la propiedad RadioButton.Content en todas las plataformas. Para más información, consulta Redefinir la apariencia de RadioButton.

Asociar valores con RadioButtons

Cada objeto RadioButton tiene una propiedad Value, de tipo object, que define un valor único opcional que se va a asociar al botón de radio. Esto permite que el valor de un elemento RadioButton sea diferente a su contenido y es especialmente útil cuando los objetos RadioButton muestran objetos View.

El XAML siguiente muestra cómo establecer las propiedades Content y Value en cada objeto RadioButton:

<StackLayout>
    <Label Text="What's your favorite animal?" />
    <RadioButton Value="Cat">
        <RadioButton.Content>
            <Image Source="cat.png" />
        </RadioButton.Content>
    </RadioButton>
    <RadioButton Value="Dog">
        <RadioButton.Content>
            <Image Source="dog.png" />
        </RadioButton.Content>
    </RadioButton>
    <RadioButton Value="Elephant">
        <RadioButton.Content>
            <Image Source="elephant.png" />
        </RadioButton.Content>
    </RadioButton>
    <RadioButton Value="Monkey">
        <RadioButton.Content>
            <Image Source="monkey.png" />
        </RadioButton.Content>
    </RadioButton>
</StackLayout>

En este ejemplo, cada RadioButton tiene Image como contenido, al tiempo que define un valor basado en cadenas. Esto permite identificar fácilmente el valor del botón de radio activado.

Agrupar RadioButtons

Los botones de radio funcionan en grupos y hay tres enfoques para agrupar botones de radio:

  • Colocarlos dentro del mismo contenedor principal. Esto se conoce como agrupación implícita.
  • Establecer la propiedad GroupName de cada botón de radio en el grupo en el mismo valor. Esto se conoce como agrupación explícita.
  • Establecer la propiedad adjunta RadioButtonGroup.GroupName en un contenedor primario, que a su vez establece la propiedad GroupName de cualquier objeto RadioButton en el contenedor. Esto también se conoce como agrupación explícita.

Importante

Los objetos RadioButton no tienen que pertenecer al mismo elemento primario que se va a agrupar. Son mutuamente excluyentes siempre que compartan un nombre de grupo.

Agrupación explícita con la propiedad GroupName

En el ejemplo de XAML siguiente se muestran objetos de agrupación explícita estableciendo RadioButton sus propiedades GroupName:

<Label Text="What's your favorite color?" />
<RadioButton Content="Red"
             GroupName="colors" />
<RadioButton Content="Green"
             GroupName="colors" />
<RadioButton Content="Blue"
             GroupName="colors" />
<RadioButton Content="Other"
             GroupName="colors" />

En este ejemplo, cada RadioButton es mutuamente excluyente porque comparte el mismo valor GroupName.

Agrupación explícita con la propiedad adjunta RadioButtonGroup.GroupName

La clase RadioButtonGroup define una propiedad adjunta GroupName, de tipo string, que se puede establecer en un objeto Layout<View>. Esto permite que cualquier diseño se convierta en un grupo de botones de radio:

<StackLayout RadioButtonGroup.GroupName="colors">
    <Label Text="What's your favorite color?" />
    <RadioButton Content="Red" />
    <RadioButton Content="Green" />
    <RadioButton Content="Blue" />
    <RadioButton Content="Other" />
</StackLayout>

En este ejemplo, cada RadioButton en la clase StackLayout tendrá su propiedad GroupName establecida en colors y será mutuamente excluyente.

Nota:

Cuando un objeto Layout<View> que establece la propiedad adjunta RadioButtonGroup.GroupName contiene un elemento RadioButton que establece su propiedad GroupName, tendrá prioridad el valor de la propiedad RadioButton.GroupName.

Responder a los cambios de estado de RadioButton

Un botón de radio tiene dos estados: seleccionado o sin seleccionar. Cuando se activa un botón de radio, su propiedad IsChecked es true. Cuando un botón de radio está sin seleccionar, su propiedad IsChecked es false. Un botón de radio se puede desactivar al hacer clic en otro botón de radio del mismo grupo, pero no al hacer clic de nuevo en él. Sin embargo, para desactivar un botón de radio mediante programación puede establecer su propiedad IsChecked en false.

Respuesta a un desencadenamiento de eventos

Cuando la propiedad IsChecked cambia, ya sea por manipulación del usuario o mediante programación, el evento CheckedChanged se desencadena. Para responder al cambio se puede registrar un controlador de eventos para este evento:

<RadioButton Content="Red"
             GroupName="colors"
             CheckedChanged="OnColorsRadioButtonCheckedChanged" />

El código subyacente contiene el controlador del evento CheckedChanged.

void OnColorsRadioButtonCheckedChanged(object sender, CheckedChangedEventArgs e)
{
    // Perform required operation
}

El argumento sender es el RadioButton responsable de este evento. Puedes usarlo para tener acceso al objeto RadioButton o para distinguir entre varios objetos RadioButton que comparten el mismo controlador de eventos CheckedChanged.

Respuesta a un cambio de propiedad

La clase RadioButtonGroup define una propiedad adjunta SelectedValue, de tipo object, que se puede establecer en un objeto Layout<View>. Esta propiedad adjunta representa el valor de RadioButton activado dentro de un grupo definido en un diseño.

Cuando cambia la propiedad IsChecked, ya sea a través de manipulación del usuario o mediante programación, la propiedad adjunta RadioButtonGroup.SelectedValue también cambia. Por lo tanto, la propiedad adjunta RadioButtonGroup.SelectedValue puede estar enlazada a una propiedad que almacena la selección del usuario:

<StackLayout RadioButtonGroup.GroupName="{Binding GroupName}"
             RadioButtonGroup.SelectedValue="{Binding Selection}">
    <Label Text="What's your favorite animal?" />
    <RadioButton Content="Cat"
                 Value="Cat" />
    <RadioButton Content="Dog"
                 Value="Dog" />
    <RadioButton Content="Elephant"
                 Value="Elephant" />
    <RadioButton Content="Monkey"
                 Value="Monkey"/>
    <Label x:Name="animalLabel">
        <Label.FormattedText>
            <FormattedString>
                <Span Text="You have chosen:" />
                <Span Text="{Binding Selection}" />
            </FormattedString>
        </Label.FormattedText>
    </Label>
</StackLayout>

En este ejemplo, el valor de la propiedad adjunta RadioButtonGroup.GroupName se establece mediante la propiedad GroupName en el contexto de enlace. Del mismo modo, el valor de la propiedad adjunta RadioButtonGroup.SelectedValue se establece mediante la propiedad Selection en el contexto de enlace. Además, la propiedad Selection se actualiza a la propiedad Value del RadioButton activado.

Estados visuales de RadioButton

Los objetos RadioButton tienen estados visuales Checked y Unchecked que se pueden usar para iniciar un cambio visual cuando RadioButton se activa o se desactiva.

En el ejemplo de XAML siguiente se muestra cómo definir un estado visual para los estados Checked y Unchecked:

<ContentPage ...>
    <ContentPage.Resources>
        <Style TargetType="RadioButton">
            <Setter Property="VisualStateManager.VisualStateGroups">
                <VisualStateGroupList>
                    <VisualStateGroup x:Name="CheckedStates">
                        <VisualState x:Name="Checked">
                            <VisualState.Setters>
                                <Setter Property="TextColor"
                                        Value="Green" />
                                <Setter Property="Opacity"
                                        Value="1" />
                            </VisualState.Setters>
                        </VisualState>
                        <VisualState x:Name="Unchecked">
                            <VisualState.Setters>
                                <Setter Property="TextColor"
                                        Value="Red" />
                                <Setter Property="Opacity"
                                        Value="0.5" />
                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateGroupList>
            </Setter>
        </Style>
    </ContentPage.Resources>
    <StackLayout>
        <Label Text="What's your favorite mode of transport?" />
        <RadioButton Content="Car" />
        <RadioButton Content="Bike" />
        <RadioButton Content="Train" />
        <RadioButton Content="Walking" />
    </StackLayout>
</ContentPage>

En este ejemplo, la clase Style implícita se destina a objetos RadioButton. El Checked VisualState especifica que cuando se comprueba un RadioButton, su propiedad TextColor se establecerá en verde con un valor de Opacity de 1. El Unchecked VisualState especifica que cuando un RadioButton está en un estado no activado, su propiedad TextColor se establecerá en rojo con un valor de Opacity de 0,5. Por lo tanto, el efecto general es que cuando un RadioButton está desactivado es rojo y parcialmente transparente, y es verde sin transparencia cuando está activado:

Captura de pantalla de los estados visuales de RadioButton

Para obtener más información sobre los estados visuales, vea Administrador de estado visual de Xamarin.Forms.

Redefinición de la apariencia de RadioButton

De manera predeterminada, los objetos RadioButton usan los representadores de la plataforma para usar controles nativos en las plataformas compatibles. Sin embargo, la estructura visual de RadioButton se puede redefinir con ControlTemplate, de modo que los objetos RadioButton tengan una apariencia idéntica en todas las plataformas. Esto es posible porque la clase RadioButton hereda de la clase TemplatedView.

El código de XAML siguiente muestra un elemento ControlTemplate que se puede usar para redefinir la estructura visual de los objetos RadioButton:

<ContentPage ...>
    <ContentPage.Resources>
        <ControlTemplate x:Key="RadioButtonTemplate">
            <Frame BorderColor="#F3F2F1"
                   BackgroundColor="#F3F2F1"
                   HasShadow="False"
                   HeightRequest="100"
                   WidthRequest="100"
                   HorizontalOptions="Start"
                   VerticalOptions="Start"
                   Padding="0">
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroupList>
                        <VisualStateGroup x:Name="CheckedStates">
                            <VisualState x:Name="Checked">
                                <VisualState.Setters>
                                    <Setter Property="BorderColor"
                                            Value="#FF3300" />
                                    <Setter TargetName="check"
                                            Property="Opacity"
                                            Value="1" />
                                </VisualState.Setters>
                            </VisualState>
                            <VisualState x:Name="Unchecked">
                                <VisualState.Setters>
                                    <Setter Property="BackgroundColor"
                                            Value="#F3F2F1" />
                                    <Setter Property="BorderColor"
                                            Value="#F3F2F1" />
                                    <Setter TargetName="check"
                                            Property="Opacity"
                                            Value="0" />
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateGroupList>
                </VisualStateManager.VisualStateGroups>
                <Grid Margin="4"
                      WidthRequest="100">
                    <Grid WidthRequest="18"
                          HeightRequest="18"
                          HorizontalOptions="End"
                          VerticalOptions="Start">
                        <Ellipse Stroke="Blue"
                                 Fill="White"
                                 WidthRequest="16"
                                 HeightRequest="16"
                                 HorizontalOptions="Center"
                                 VerticalOptions="Center" />
                        <Ellipse x:Name="check"
                                 Fill="Blue"
                                 WidthRequest="8"
                                 HeightRequest="8"
                                 HorizontalOptions="Center"
                                 VerticalOptions="Center" />
                    </Grid>
                    <ContentPresenter />
                </Grid>
            </Frame>
        </ControlTemplate>

        <Style TargetType="RadioButton">
            <Setter Property="ControlTemplate"
                    Value="{StaticResource RadioButtonTemplate}" />
        </Style>
    </ContentPage.Resources>
    <!-- Page content -->
</ContentPage>

En este ejemplo, el elemento raíz de ControlTemplate es un objeto Frame que define estados visuales Checked y Unchecked. El objeto Frame usa una combinación de objetos Grid, Ellipse, ContentPresenter para definir la estructura visual de un objeto RadioButton. En el ejemplo también se incluye un estilo implícito que asignará RadioButtonTemplate a la propiedad ControlTemplate de cualquier objeto RadioButton de la página.

Nota:

El objeto ContentPresenter marca la ubicación en la estructura visual donde el contenido de RadioButton se mostrará.

En el siguiente ejemplo de XAML se muestran objetos RadioButton que consumen ControlTemplate a través del estilo implícito:

<StackLayout>
    <Label Text="What's your favorite animal?" />
    <StackLayout RadioButtonGroup.GroupName="animals"
                 Orientation="Horizontal">
        <RadioButton Value="Cat">
            <RadioButton.Content>
                <StackLayout>
                    <Image Source="cat.png"
                           HorizontalOptions="Center"
                           VerticalOptions="CenterAndExpand" />
                    <Label Text="Cat"
                           HorizontalOptions="Center"
                           VerticalOptions="End" />
                </StackLayout>
            </RadioButton.Content>
        </RadioButton>
        <RadioButton Value="Dog">
            <RadioButton.Content>
                <StackLayout>
                    <Image Source="dog.png"
                           HorizontalOptions="Center"
                           VerticalOptions="CenterAndExpand" />
                    <Label Text="Dog"
                           HorizontalOptions="Center"
                           VerticalOptions="End" />
                </StackLayout>
            </RadioButton.Content>
        </RadioButton>
        <RadioButton Value="Elephant">
            <RadioButton.Content>
                <StackLayout>
                    <Image Source="elephant.png"
                           HorizontalOptions="Center"
                           VerticalOptions="CenterAndExpand" />
                    <Label Text="Elephant"
                           HorizontalOptions="Center"
                           VerticalOptions="End" />
                </StackLayout>
            </RadioButton.Content>
        </RadioButton>
        <RadioButton Value="Monkey">
            <RadioButton.Content>
                <StackLayout>
                    <Image Source="monkey.png"
                           HorizontalOptions="Center"
                           VerticalOptions="CenterAndExpand" />
                    <Label Text="Monkey"
                           HorizontalOptions="Center"
                           VerticalOptions="End" />
                </StackLayout>
            </RadioButton.Content>
        </RadioButton>
    </StackLayout>
</StackLayout>

En este ejemplo, la estructura visual definida para cada RadioButton se reemplaza por la estructura visual definida en ControlTemplate y, por tanto, en tiempo de ejecución, los objetos de ControlTemplate se convierten en parte del árbol visual para cada RadioButton. Además, el contenido de cada RadioButton se sustituye por ContentPresenter definido en la plantilla de control. Esto da como resultado la siguiente apariencia de RadioButton:

Captura de pantalla de RadioButtons con plantilla

Para obtener más información sobre las plantillas de control, consulte Plantillas de control de Xamarin.Forms.

Deshabilitar un radioButton

A veces, una aplicación entra en un estado en el que una comprobación de RadioButton no es una operación válida. En tales casos, se puede deshabilitar el objeto RadioButton estableciendo su propiedad IsEnabled en false.