.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
相关产品推荐
相关产品推荐

