You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Maui 如何通过C#代码创建RadioButton的ControlTemplate

用C#代码实现自定义RadioButton的ControlTemplate

以下是将你提供的XAML模板完整转换为C#代码的实现,完全匹配原模板的视觉样式和状态切换逻辑:

步骤1:构建ControlTemplate的视觉树

先创建模板的根容器和内部控件结构:

// 创建根Border
var rootBorder = new Border
{
    Stroke = Color.FromArgb(255, 243, 242, 241), // #F3F2F1
    StrokeThickness = 0,
    StrokeShape = new RoundRectangle { CornerRadius = new CornerRadius(10) },
    BackgroundColor = Colors.Transparent,
    HorizontalOptions = LayoutOptions.Start,
    VerticalOptions = LayoutOptions.Start
};

// 创建内部Grid
var innerGrid = new Grid { Margin = new Thickness(5) };
innerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
innerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });

// 创建单选按钮图标容器Grid
var iconGrid = new Grid
{
    GridColumn = 0,
    Margin = new Thickness(0, 0, 4, 0),
    WidthRequest = 18,
    HeightRequest = 18,
    HorizontalOptions = LayoutOptions.End,
    VerticalOptions = LayoutOptions.Start
};

// 外层椭圆(边框)
var outerEllipse = new Ellipse
{
    Stroke = Color.FromArgb(255, 99, 188, 205), // #63BBCD
    Fill = Colors.White,
    WidthRequest = 16,
    HeightRequest = 16,
    HorizontalOptions = LayoutOptions.Center,
    VerticalOptions = LayoutOptions.Center
};

// 选中填充椭圆(命名为check,用于状态切换)
var checkEllipse = new Ellipse
{
    Name = "check",
    Fill = Color.FromArgb(255, 99, 188, 205), // #63BBCD
    WidthRequest = 16,
    HeightRequest = 16,
    HorizontalOptions = LayoutOptions.Center,
    VerticalOptions = LayoutOptions.Center,
    Opacity = 0 // 默认未选中透明
};

// 添加椭圆到图标Grid
iconGrid.Children.Add(outerEllipse);
iconGrid.Children.Add(checkEllipse);

// 创建内容展示器
var contentPresenter = new ContentPresenter { GridColumn = 1 };

// 添加子控件到内部Grid
innerGrid.Children.Add(iconGrid);
innerGrid.Children.Add(contentPresenter);

// 将内部Grid设为根Border的子控件
rootBorder.Content = innerGrid;

步骤2:添加视觉状态管理

对应原XAML中的VisualStateGroups,构建Checked/Unchecked状态切换逻辑:

// 创建视觉状态组列表
var visualStateGroupList = new VisualStateGroupList();

// 创建CheckedStates状态组
var checkedStateGroup = new VisualStateGroup { Name = "CheckedStates" };

// 构建Checked状态
var checkedState = new VisualState { Name = "Checked" };
checkedState.Setters.Add(new Setter { Property = Border.StrokeProperty, Value = Color.FromArgb(255, 255, 51, 0) }); // #FF3300
checkedState.Setters.Add(new Setter { TargetName = "check", Property = VisualElement.OpacityProperty, Value = 1 });

// 构建Unchecked状态
var uncheckedState = new VisualState { Name = "Unchecked" };
uncheckedState.Setters.Add(new Setter { Property = VisualElement.BackgroundColorProperty, Value = Colors.Transparent });
uncheckedState.Setters.Add(new Setter { Property = Border.StrokeProperty, Value = Color.FromArgb(255, 243, 242, 241) }); // #F3F2F1
uncheckedState.Setters.Add(new Setter { TargetName = "check", Property = VisualElement.OpacityProperty, Value = 0 });

// 将状态添加到状态组
checkedStateGroup.States.Add(checkedState);
checkedStateGroup.States.Add(uncheckedState);

// 将状态组添加到列表
visualStateGroupList.Add(checkedStateGroup);

// 关联视觉状态到根Border
VisualStateManager.SetVisualStateGroups(rootBorder, visualStateGroupList);

步骤3:创建ControlTemplate并应用到RadioButton

将构建好的视觉树和状态管理整合为ControlTemplate,然后通过Style或直接赋值给RadioButton:

// 创建ControlTemplate
var radioButtonTemplate = new ControlTemplate(() => rootBorder);

// 方式1:创建全局Style应用到所有RadioButton
var radioButtonStyle = new Style(typeof(RadioButton));
radioButtonStyle.Setters.Add(new Setter { Property = RadioButton.ControlTemplateProperty, Value = radioButtonTemplate });
Application.Current.Resources.Add(typeof(RadioButton), radioButtonStyle);

// 方式2:直接给单个RadioButton赋值
var customRadioButton = new RadioButton
{
    ControlTemplate = radioButtonTemplate,
    Content = "自定义单选按钮"
};

这样就能完全复现你原XAML模板的效果,所有属性、状态切换逻辑都和原模板一致。

内容的提问来源于stack exchange,提问作者vordonez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 01:17:41