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

.NET 8 MAUI中RadioButton默认值设置及绑定失效问题

.NET 8 MAUI自定义RadioButton绑定问题解决方案

1. 确保ViewModel实现INotifyPropertyChanged

ViewModel必须实现该接口,否则属性变更无法同步到UI。示例代码:

public class MainViewModel : INotifyPropertyChanged
{
    private string _selected = "Hot Dishes";
    public string Selected
    {
        get => _selected;
        set
        {
            if (_selected != value)
            {
                _selected = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler? PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    // 分类数据源示例
    public List<string> Categories { get; } = new List<string> { "Hot Dishes", "Cold Dishes", "Desserts" };
}

2. 修正自定义RadioButton的实现

自定义控件需正确处理IsChecked属性,并与RadioButtonGroup的选中值联动:

public class CustomRadioButton : ContentView
{
    public static readonly BindableProperty IsCheckedProperty =
        BindableProperty.Create(nameof(IsChecked), typeof(bool), typeof(CustomRadioButton), false,
            propertyChanged: OnIsCheckedChanged);

    public static readonly BindableProperty TextProperty =
        BindableProperty.Create(nameof(Text), typeof(string), typeof(CustomRadioButton), string.Empty);

    public bool IsChecked
    {
        get => (bool)GetValue(IsCheckedProperty);
        set => SetValue(IsCheckedProperty, value);
    }

    public string Text
    {
        get => (string)GetValue(TextProperty);
        set => SetValue(TextProperty, value);
    }

    public CustomRadioButton()
    {
        var tapGesture = new TapGestureRecognizer();
        tapGesture.Tapped += (s, e) => IsChecked = !IsChecked;
        GestureRecognizers.Add(tapGesture);

        // 自定义UI示例(可替换为你的个性化布局)
        Content = new Label
        {
            BindingContext = this,
            Text = "{Binding Text}",
            Padding = new Thickness(10,5)
        };
    }

    private static void OnIsCheckedChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var radio = (CustomRadioButton)bindable;
        if ((bool)newValue)
        {
            var group = radio.Parent as RadioButtonGroup;
            group?.SetValue(RadioButtonGroup.SelectedValueProperty, radio.Text);
        }
    }
}

3. 调整XAML中的绑定逻辑

确保RadioButtonGroup的SelectedValue使用双向绑定,同时通过转换器关联自定义RadioButton的IsChecked状态:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:YourAppNamespace"
             x:Class="YourAppNamespace.MainPage"
             BindingContext="{StaticResource MainViewModel}">

    <RadioButtonGroup SelectedValue="{Binding Selected, Mode=TwoWay}">
        <BindableLayout.ItemsSource>
            <Binding Path="Categories" />
        </BindableLayout.ItemsSource>
        <BindableLayout.ItemTemplate>
            <DataTemplate>
                <local:CustomRadioButton 
                    Text="{Binding .}"
                    IsChecked="{Binding Source={RelativeSource AncestorType={x:Type RadioButtonGroup}}, Path=SelectedValue, Converter={StaticResource StringEqualsConverter}, ConverterParameter={Binding .}}" />
            </DataTemplate>
        </BindableLayout.ItemTemplate>
    </RadioButtonGroup>
</ContentPage>

4. 添加字符串比较转换器

用于判断当前项是否与选中值匹配,实现双向同步:

public class StringEqualsConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return string.Equals(value?.ToString(), parameter?.ToString(), StringComparison.OrdinalIgnoreCase);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (bool)value ? parameter : Binding.DoNothing;
    }
}

在App.xaml中注册转换器和ViewModel:

<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:YourAppNamespace"
             x:Class="YourAppNamespace.App">
    <Application.Resources>
        <ResourceDictionary>
            <local:StringEqualsConverter x:Key="StringEqualsConverter" />
            <local:MainViewModel x:Key="MainViewModel" />
        </ResourceDictionary>
    </Application.Resources>
</Application>

5. 验证绑定上下文

确认MainPage的BindingContext已正确赋值,可通过代码后台或XAML静态资源设置:

public MainPage()
{
    InitializeComponent();
    // 若未通过XAML设置,可在此赋值
    // BindingContext = new MainViewModel();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 01:42:39