Xamarin 动态代码生成网格中单选按钮的文本答案绑定问题
Xamarin 动态代码生成网格中单选按钮的文本答案绑定问题
嗨,别担心,新手遇到这种绑定问题太正常啦!我来帮你理清楚怎么把单选按钮对应的文本(Pass/Fix/Fail)存到你的PassFixFail字段里~
你现在遇到的问题是,单选按钮默认绑定IsChecked返回的是布尔值(选中/未选中),但你需要的是按钮对应的文本字符串。给你两种简单的实现方法,选你觉得顺手的来:
方法一:用选中事件直接赋值(新手友好,直观好懂)
这种方法不需要复杂的绑定,直接给每个动态创建的单选按钮加个选中事件,一旦选中就把对应的字符串塞进你的问题模型里。
首先,先确保你的问题模型(比如叫Question)有PassFixFail属性,而且最好实现INotifyPropertyChanged(这样属性变化时能通知UI,可选但推荐):
public class Question : INotifyPropertyChanged { private string _passFixFail; public string PassFixFail { get => _passFixFail; set { _passFixFail = value; OnPropertyChanged(); } } // 你的其他问题属性,比如问题文本 public string QuestionText { get; set; } // 实现INotifyPropertyChanged的标准代码 public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
然后,当你动态创建网格里的单选按钮时,给每个按钮绑定CheckedChanged事件:
// 假设你有一个问题列表questions,还有要把行加进去的主网格mainGrid foreach (var question in questions) { // 新建一行放问题和单选按钮 var questionRow = new Grid(); // 先加问题文本标签 questionRow.Children.Add(new Label { Text = question.QuestionText }); // 分别创建三个单选按钮,注意给同一问题的按钮设相同的GroupName,保证互斥 var passBtn = new RadioButton { Text = "Pass", GroupName = $"Q_{question.GetHashCode()}" }; var fixBtn = new RadioButton { Text = "Fix", GroupName = $"Q_{question.GetHashCode()}" }; var failBtn = new RadioButton { Text = "Fail", GroupName = $"Q_{question.GetHashCode()}" }; // 给每个按钮加选中事件:只有当按钮被选中时,才给PassFixFail赋值 passBtn.CheckedChanged += (sender, e) => { if (e.Value) // e.Value是布尔值,true表示选中 question.PassFixFail = "Pass"; }; fixBtn.CheckedChanged += (sender, e) => { if (e.Value) question.PassFixFail = "Fix"; }; failBtn.CheckedChanged += (sender, e) => { if (e.Value) question.PassFixFail = "Fail"; }; // 把三个按钮加到当前行里 questionRow.Children.Add(passBtn); questionRow.Children.Add(fixBtn); questionRow.Children.Add(failBtn); // 把这一行加到主网格 mainGrid.Children.Add(questionRow); }
这样一来,用户点哪个单选按钮,对应的字符串就会直接存在PassFixFail里了,完全不用管布尔值的问题~
方法二:用MVVM命令绑定(更规范的写法)
如果你想贴合Xamarin的MVVM开发模式,也可以用命令来实现,不用直接写事件:
首先在你的ViewModel里加一个命令,用来处理选中事件:
public class YourViewModel { // 你的问题列表 public ObservableCollection<Question> Questions { get; set; } // 处理选中答案的命令 public ICommand SelectAnswerCommand => new Command<(Question Question, string Answer)>(SetAnswer); private void SetAnswer((Question Question, string Answer) param) { param.Question.PassFixFail = param.Answer; } }
然后动态创建单选按钮时,绑定命令和参数:
// 假设你已经拿到了viewModel实例 foreach (var question in viewModel.Questions) { var questionRow = new Grid(); questionRow.Children.Add(new Label { Text = question.QuestionText }); var passBtn = new RadioButton { Text = "Pass", GroupName = $"Q_{question.GetHashCode()}", Command = viewModel.SelectAnswerCommand, CommandParameter = (Question: question, Answer: "Pass") // 把问题和答案文本一起传进去 }; var fixBtn = new RadioButton { Text = "Fix", GroupName = $"Q_{question.GetHashCode()}", Command = viewModel.SelectAnswerCommand, CommandParameter = (Question: question, Answer: "Fix") }; var failBtn = new RadioButton { Text = "Fail", GroupName = $"Q_{question.GetHashCode()}", Command = viewModel.SelectAnswerCommand, CommandParameter = (Question: question, Answer: "Fail") }; questionRow.Children.Add(passBtn); questionRow.Children.Add(fixBtn); questionRow.Children.Add(failBtn); mainGrid.Children.Add(questionRow); }
这种写法更符合MVVM的分离原则,适合后续项目扩展~
最后提醒你一下,不管用哪种方法,GroupName一定要给同一问题的三个单选按钮设成相同的值,这样才能保证同一时间只能选一个哦!
备注:内容来源于stack exchange,提问作者Tanya
相关产品推荐
相关产品推荐

