Xamarin动态创建问卷:实现单选按钮互斥选中功能
实现单选按钮组的互斥选中功能
看起来你已经搞定了问卷单选按钮的动态渲染,现在就差同一问题下单选按钮的互斥选中功能了对吧?我给你两个实用方案,你可以根据你的CustomRadioButton实现情况来选:
方案一:利用GroupName属性(推荐,如果你的CustomRadioButton支持)
如果你的CustomRadioButton是基于Xamarin.Forms原生RadioButton扩展的,那原生控件本身就自带GroupName属性——同一组名的单选按钮会自动实现互斥选中。你只需要在创建按钮时,给同一问题下的所有单选按钮设置相同的组名就行:
foreach (var item in Settings.VOCQuestionDetailsSettings.RespondantQuestionnare) { myGrid.Children.Add(new Label { Text = item.Questions, TextColor = Color.Black, HorizontalOptions = LayoutOptions.FillAndExpand, FontAttributes = FontAttributes.Bold }, 0, rowCount); rowCount++; // 给当前问题设置唯一组名,比如用问题文本的哈希值做标识,确保每组唯一 var questionGroupName = $"QuestionGroup_{item.Questions.GetHashCode()}"; for (int i = 0; i < item.Choices.Count; i++) { if (item.QuestionType == "Radio") { myGrid.Children.Add(new CustomRadioButton { HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.FillAndExpand, Text = item.Choices[i], TextColor = Color.Black, FontSize = 14, // 关键:同一问题的单选按钮设置相同GroupName GroupName = questionGroupName }, 0, rowCount); rowCount++; } } }
设置完组名后,同一组的单选按钮会自动处理互斥逻辑:选中其中一个时,同组其他按钮会自动取消选中,完全不用额外写事件处理代码。
方案二:手动绑定选中事件处理互斥(如果CustomRadioButton没有GroupName)
如果你的CustomRadioButton没实现GroupName功能,那可以手动给每个按钮添加CheckedChanged事件,当某个按钮被选中时,遍历同一问题下的其他按钮,把它们的IsChecked设为false:
foreach (var item in Settings.VOCQuestionDetailsSettings.RespondantQuestionnare) { myGrid.Children.Add(new Label { Text = item.Questions, TextColor = Color.Black, HorizontalOptions = LayoutOptions.FillAndExpand, FontAttributes = FontAttributes.Bold }, 0, rowCount); rowCount++; // 先把当前问题的所有单选按钮存到列表里,方便后续批量处理 List<CustomRadioButton> currentQuestionRadios = new List<CustomRadioButton>(); for (int i = 0; i < item.Choices.Count; i++) { if (item.QuestionType == "Radio") { var radioBtn = new CustomRadioButton { HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.FillAndExpand, Text = item.Choices[i], TextColor = Color.Black, FontSize = 14 }; // 绑定选中状态变化事件 radioBtn.CheckedChanged += (sender, e) => { if (e.Value) // 只有当前按钮被选中时才处理 { // 遍历同组其他按钮,取消选中状态 foreach (var otherRadio in currentQuestionRadios) { if (otherRadio != sender) { otherRadio.IsChecked = false; } } } }; currentQuestionRadios.Add(radioBtn); myGrid.Children.Add(radioBtn, 0, rowCount); rowCount++; } } }
这里要注意:如果你的CustomRadioButton还没暴露IsChecked属性和CheckedChanged事件,得先在自定义控件里补上这些基础功能,示例代码如下:
public class CustomRadioButton : View { // 定义IsChecked绑定属性 public static readonly BindableProperty IsCheckedProperty = BindableProperty.Create(nameof(IsChecked), typeof(bool), typeof(CustomRadioButton), false); // 定义Text绑定属性(如果还没实现) 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); } // 定义CheckedChanged事件,用于通知外部状态变化 public event EventHandler<bool> CheckedChanged; // 当IsChecked属性变化时触发事件 protected override void OnPropertyChanged(string propertyName = null) { base.OnPropertyChanged(propertyName); if (propertyName == IsCheckedProperty.PropertyName) { CheckedChanged?.Invoke(this, IsChecked); } } }
内容的提问来源于stack exchange,提问作者Shagun Singh
相关产品推荐
相关产品推荐

