RadioButton

浏览示例。 浏览示例

.NET 多平台应用程序 UI(.NET MAUI)RadioButton 是一种按钮,允许用户从一组选项中选择一个。 每个选项都由一个单选按钮表示,你只能在组中选择一个单选按钮。 默认情况下,每个 RadioButton 显示文本:

RadioButtons 的屏幕截图。

但是,在某些平台上,一个 RadioButton 可以显示一个 View,并且在所有平台上,每个 RadioButton 的外观都可以用 ControlTemplate 重新定义。

重新定义的 RadioButtons 的屏幕截图。

RadioButton 定义以下属性:

  • Content,类型为object,用于定义由RadioButton显示的stringView
  • IsChecked,类型 bool,用于定义是否检查RadioButton。 此属性使用 TwoWay 绑定,默认值为 false.
  • GroupName 是类型为 string 的元素,用于定义一个名称以指定哪些 RadioButton 控件是互斥的。 此属性的默认值为 null.
  • ,类型,定义与关联的一个可选的唯一值。
  • BorderColor,类型 Color,用于定义边框笔划颜色。
  • BorderWidth,类型 double,用于定义边框的 RadioButton 宽度。
  • CharacterSpacing,类型 double,用于定义任何显示文本的字符之间的间距。
  • CornerRadius,类型为int,用于定义RadioButton的圆角半径。
  • FontAttributes,类型 FontAttributes,用于确定文本样式。
  • FontAutoScalingEnabled,类型 bool,用于定义应用的 UI 是否反映操作系统中设置的文本缩放设置。 此属性的默认值为 true
  • FontFamily,类型 string,用于定义字体系列。
  • FontSize,类型 double,用于定义字号。
  • TextColor,类型 Color,用于定义任何显示文本的颜色。
  • TextTransform,类型 TextTransform,用于定义任何显示文本的大小写。

这些属性由 BindableProperty 对象提供支持,表示它们可以是数据绑定的目标,并可以设置样式。

RadioButton 还定义在 CheckedChanged 属性更改时 IsChecked 通过用户或编程操作引发的事件。 事件附带的对象具有一个名为的属性,其类型为。 引发事件时,属性的值 CheckedChangedEventArgs.Value 将设置为该属性的新值 IsChecked

RadioButton 组可以由 RadioButtonGroup 类管理,该类定义以下附加属性:

  • GroupName,类型为string,用于在ILayout中定义RadioButton对象的组名称。
  • SelectedValue,类型为 object,用于表示 ILayout 组中选中的 RadioButton 对象的值。 默认情况下,此附加属性使用 TwoWay 绑定。

小窍门

尽管不是强制性的,但强烈建议设置 GroupName 属性,以确保 SelectedValue 该属性在所有平台上都能正常工作。

有关GroupName附加属性的详细信息,请参阅Group RadioButtons。 有关 SelectedValue 附加属性的详细信息,请参阅 响应 RadioButton 状态变化

创建 RadioButtons

RadioButton 的外观由分配给 RadioButton.Content 属性的数据类型所定义。

  • RadioButton.Content 属性被赋予 string 后,它将在每个平台上显示,并水平对齐到了单选按钮圆圈的旁边。
  • RadioButton.Content被分配为View时,它将在受支持的平台(iOS,Windows)上显示,而对于不支持的平台(如Android),将回退到View对象的字符串表示形式。 在这两种情况下,文本内容与单选按钮的圆圈水平对齐。
  • 应用ControlTemplateRadioButton时,可以在所有平台上将View分配给RadioButton.Content属性。 有关详细信息,请参阅 重新定义 RadioButton 外观

显示基于字符串的内容

Content属性被分配string时,RadioButton显示文本。

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

在此示例中, RadioButton 对象将隐式分组到同一个父容器内。 此 XAML 导致以下屏幕截图中所示的外观:

基于文本的 RadioButtons 的屏幕截图。

显示任意内容

在 iOS 和 Windows 系统中,当Content属性被分配给RadioButton时,View可以显示任意内容。

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

在此示例中, RadioButton 对象将隐式分组到同一个父容器内。 此 XAML 导致以下屏幕截图中所示的外观:

基于视图的 RadioButtons 的屏幕截图。

在 Android 上,RadioButton 对象将显示作为内容的 View 对象的字符串表示形式。

注释

ControlTemplate被应用于RadioButton时,可以将View分配给所有平台上的RadioButton.Content属性。 有关详细信息,请参阅 重新定义 RadioButton 外观

将值与 RadioButtons 关联

每个 RadioButton 对象都有一个类型为 objectValue 属性,该属性定义一个与单选按钮关联的可选唯一值。 这使得RadioButton的值可以与内容不同,这在RadioButton对象显示View对象时特别有用。

以下 XAML 显示在每个Content对象上设置ValueRadioButton属性:

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

在此示例中,每个示例 RadioButton 都有一个 Image 作为其内容,同时还定义基于字符串的值。 这样就可以轻松识别选中的单选按钮的值。

分组单选按钮

单选按钮以组方式工作,可通过三种方法对单选按钮进行分组:

  • 将它们放在同一个父容器中。 这称为 隐式 分组。
  • 将组中的每个单选按钮的 GroupName 属性设置为相同的值。 这称为 显式 分组。
  • RadioButtonGroup.GroupName 父容器上设置附加属性,后者又设置 GroupName 容器中任何 RadioButton 对象的属性。 这也称为 显式 分组。

重要

RadioButton 对象可以分组而不必属于同一个父级。 它们在共享组名称的条件下是相互排斥的。

使用 GroupName 属性进行显式分组

以下 XAML 示例显示通过设置他们的GroupName属性来显式分组RadioButton 对象:

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

在此示例中,每个 RadioButton 是互斥的,因为它们共享相同的 GroupName 值。

使用 RadioButtonGroup.GroupName 附加属性进行显式分组

RadioButtonGroup类定义了一个附加属性,类型为string,可在Layout<View>对象上设置。 这样,任何布局都可以转换为单选按钮组:

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

在此示例中,StackLayout 中的每个 RadioButtonGroupName 属性都被设置为 colors,并且这些属性是互斥的。

注释

当一个设置RadioButtonGroup.GroupName附加属性的ILayout对象包含一个设置其GroupName属性的RadioButton对象时,RadioButton.GroupName属性的值将优先。

响应 RadioButton 状态更改

单选按钮有两种状态:已选中或未选中。 选中单选按钮时,其 IsChecked 属性变为 true。 取消选中单选按钮时,其 IsChecked 属性为 false。 可以通过点击同一组中的另一个单选按钮来清除单选按钮,但再次点击无法清除该按钮。 但是,可以通过以编程方式将单选按钮的 IsChecked 属性设置为 false来清除它。

响应事件触发

IsChecked属性因用户或程序操作而发生更改时,CheckedChanged事件将被触发。 可以注册此事件的事件处理程序以响应更改:

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

代码隐藏文件中包含CheckedChanged事件的处理程序:

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

sender 参数负责 RadioButton 此事件。 可以使用它访问RadioButton对象,或区分共享同一RadioButton事件处理程序的多个CheckedChanged对象。

响应属性更改

RadioButtonGroup 类定义一个 SelectedValue 附加属性,该属性的类型 object,可以在对象 ILayout 上设置。 此附加属性表示在布局上定义的组中,RadioButton 的已选值。

IsChecked属性在用户或编程操作下更改时,RadioButtonGroup.SelectedValue附加属性也将随之更改。 因此, RadioButtonGroup.SelectedValue 附加属性可以是绑定到存储用户选择的属性的数据:

<ContentPage ...
             xmlns:local="clr-namespace:RadioButtonDemos"
             x:DataType="local:AnimalViewModel">
    <StackLayout Margin="10"
                 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>
</ContentPage>

在此示例中,附加属性的值 RadioButtonGroup.GroupNameGroupName 绑定上下文中的属性设置。 同样,附加属性的值 RadioButtonGroup.SelectedValue 由绑定上下文的 Selection 属性设置。 此外,将 Selection 属性更新为经检查的 RadioButtonValue 属性。

RadioButton 视觉状态

RadioButton 对象具有 CheckedUnchecked 视觉状态,可用于当 RadioButton 被选中或取消选中时启动视觉更改。

以下 XAML 示例演示如何为Checked状态和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>

在此示例中,隐式Style 针对RadioButton 对象。 指定当检查RadioButton时,CheckedVisualStateTextColor属性将被设置为绿色,并且Opacity值为1。 指定 UncheckedVisualState 当某个 RadioButton 处于未选中状态时,其 TextColor 属性将设置为红色, Opacity 值为 0.5。 因此,总体效果是,当RadioButton被取消选中时,它呈现红色并具有部分透明效果;而被选中时,它呈现绿色且完全不透明。

RadioButton 视觉状态的屏幕截图。

有关视觉状态的详细信息,请参阅 视觉状态

重新定义 RadioButton 外观

默认情况下,RadioButton 对象利用处理程序在受支持的平台上使用原生控件。 但是, RadioButton 可以使用 a ControlTemplate重新定义视觉结构,以便 RadioButton 对象在所有平台上具有相同的外观。 这是可能的,因为 RadioButton 类继承自 TemplatedView 类。

以下 XAML 显示了如何使用 ControlTemplate 来重新定义 RadioButton 对象的视觉结构:

<ContentPage ...>
    <ContentPage.Resources>
        <ControlTemplate x:Key="RadioButtonTemplate">
            <Border Stroke="#F3F2F1"
                    StrokeThickness="2"
                    StrokeShape="RoundRectangle 10"
                    BackgroundColor="#F3F2F1"
                    HeightRequest="90"
                    WidthRequest="90"
                    HorizontalOptions="Start"
                    VerticalOptions="Start">
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroupList>
                        <VisualStateGroup x:Name="CheckedStates">
                            <VisualState x:Name="Checked">
                                <VisualState.Setters>
                                    <Setter Property="Stroke"
                                            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="Stroke"
                                            Value="#F3F2F1" />
                                    <Setter TargetName="check"
                                            Property="Opacity"
                                            Value="0" />
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateGroupList>
                </VisualStateManager.VisualStateGroups>
                <Grid Margin="4"
                      WidthRequest="90">
                    <Grid Margin="0,0,4,0"
                          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>
            </Border>
        </ControlTemplate>

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

在此示例中,根元素 ControlTemplate 是一个 Border 定义 CheckedUnchecked 视觉状态的对象。 该Border对象使用GridEllipseContentPresenter对象的组合来定义RadioButton的可视结构。 该示例还包括一个隐式样式,它将把RadioButtonTemplate分配给页面上任何RadioButton对象的ControlTemplate属性。

注释

ContentPresenter 对象标记出视觉结构中将显示 RadioButton 内容的位置。

以下 XAML 显示RadioButton对象通过隐式样式使用ControlTemplate

<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="Center" />
                    <Label Text="Cat"
                           HorizontalOptions="Center"
                           VerticalOptions="End" />
                </StackLayout>
            </RadioButton.Content>
        </RadioButton>
        <RadioButton Value="Dog">
            <RadioButton.Content>
                <StackLayout>
                    <Image Source="dog.png"
                           HorizontalOptions="Center"
                           VerticalOptions="Center" />
                    <Label Text="Dog"
                           HorizontalOptions="Center"
                           VerticalOptions="End" />
                </StackLayout>
            </RadioButton.Content>
        </RadioButton>
        <RadioButton Value="Elephant">
            <RadioButton.Content>
                <StackLayout>
                    <Image Source="elephant.png"
                           HorizontalOptions="Center"
                           VerticalOptions="Center" />
                    <Label Text="Elephant"
                           HorizontalOptions="Center"
                           VerticalOptions="End" />
                </StackLayout>
            </RadioButton.Content>
        </RadioButton>
        <RadioButton Value="Monkey">
            <RadioButton.Content>
                <StackLayout>
                    <Image Source="monkey.png"
                           HorizontalOptions="Center"
                           VerticalOptions="Center" />
                    <Label Text="Monkey"
                           HorizontalOptions="Center"
                           VerticalOptions="End" />
                </StackLayout>
            </RadioButton.Content>
        </RadioButton>
    </StackLayout>
</StackLayout>

在此示例中,为每个 RadioButton 定义的视觉结构被替换为 ControlTemplate 中定义的视觉结构,这样在运行时 ControlTemplate 的对象将成为每个 RadioButton 视觉树的一部分。 此外,每个RadioButton的内容会被替换为控件模板ContentPresenter中定义的内容。 这会导致以下 RadioButton 外观:

模板化的 RadioButtons 的屏幕截图。

有关控件模板的详细信息,请参阅 控件模板

禁用该 RadioButton

有时,应用进入一种状态,在这种状态下,检查 RadioButton 不是一个有效的操作。 在这种情况下,RadioButton 可以通过将其 IsEnabled 属性设置为 false 来禁用。