如何用更优雅的C#写法替代单选按钮切换TextBox文本的多If逻辑?
我有一个WinForms窗体,包含两个GroupBox,每个GroupBox内有若干RadioButton。选中RadioButton时需要修改同GroupBox内的TextBox文本,目前用多段If语句实现,但想找更优雅的写法。
现有实现代码
if (radioButton_5_1.Checked == true) { this.textBox_5_0.Text = MyCommands.GetDetailValue(5, 0); this.textBox_5_1.Text = MyCommands.GetDetailValue(5, 1); // ... 省略中间重复代码 this.textBox_5_8.Text = MyCommands.GetDetailValue(5, 8); } if (radioButton_5_2.Checked == true) { this.textBox_5_0.Text = MyCommands.GetDetailValue(6, 0); this.textBox_5_1.Text = MyCommands.GetDetailValue(6, 1); // ... 省略中间重复代码 this.textBox_5_8.Text = MyCommands.GetDetailValue(6, 8); } if (radioButton_5_3.Checked == true) { this.textBox_5_0.Text = MyCommands.GetDetailValue(7, 0); this.textBox_5_1.Text = MyCommands.GetDetailValue(7, 1); // ... 省略中间重复代码 this.textBox_5_8.Text = MyCommands.GetDetailValue(7, 8); } if (radioButton_5_4.Checked == true) { this.textBox_5_0.Text = MyCommands.GetDetailValue(8, 0); this.textBox_5_1.Text = MyCommands.GetDetailValue(8, 1); // ... 省略中间重复代码 this.textBox_5_8.Text = MyCommands.GetDetailValue(8, 8); } if (radioButton_19_1.Checked == true) { this.textBox_19_0.Text = MyCommands.GetDetailValue(19, 0); this.textBox_19_1.Text = MyCommands.GetDetailValue(19, 1); } if (radioButton_19_2.Checked == true) { this.textBox_19_0.Text = MyCommands.GetDetailValue(20, 0); this.textBox_19_1.Text = MyCommands.GetDetailValue(20, 1); } if (radioButton_19_3.Checked == true) { this.textBox_19_0.Text = MyCommands.GetDetailValue(21, 0); this.textBox_19_1.Text = MyCommands.GetDetailValue(21, 1); }
规则说明
- 名称带
5的TextBox和RadioButton属于groupBox_0;名称带19的属于groupBox_1 GetDetailValue第一个参数规则:groupBox_0内,RadioButton名称后缀为1时参数是5,后缀2时是6,以此类推groupBox_1内,RadioButton名称后缀为1时参数是19,后缀2时是20,以此类推
GetDetailValue第二个参数规则:对应TextBox名称的后缀数字(比如textBox_5_0后缀是0,参数就传0)
优雅实现方案
方案1:利用控件Tag属性+统一事件处理
给RadioButton设置Tag:
给每个RadioButton的Tag属性存储对应的GetDetailValue第一个参数值,比如:radioButton_5_1的Tag设为5radioButton_5_2的Tag设为6radioButton_19_1的Tag设为19- 以此类推
给所有RadioButton绑定同一个CheckedChanged事件:
所有RadioButton的CheckedChanged事件都指向同一个处理方法,比如RadioButton_CheckedChanged编写事件处理逻辑:
private void RadioButton_CheckedChanged(object sender, EventArgs e) { var radioButton = sender as RadioButton; if (radioButton == null || !radioButton.Checked) return; var groupBox = radioButton.Parent as GroupBox; if (groupBox == null) return; if (!int.TryParse(radioButton.Tag.ToString(), out int firstParam)) return; foreach (Control ctrl in groupBox.Controls) { if (ctrl is TextBox textBox) { if (int.TryParse(textBox.Name.Split('_').Last(), out int secondParam)) { textBox.Text = MyCommands.GetDetailValue(firstParam, secondParam); } } } }
方案2:提取通用方法,解析控件名称
如果不想用Tag属性,可通过解析控件名称获取参数,再调用通用方法更新TextBox:
// 通用更新方法 private void UpdateTextBoxes(int firstParam, GroupBox targetGroupBox) { foreach (Control ctrl in targetGroupBox.Controls) { if (ctrl is TextBox textBox) { if (int.TryParse(textBox.Name.Split('_').Last(), out int secondParam)) { textBox.Text = MyCommands.GetDetailValue(firstParam, secondParam); } } } } // GroupBox0的RadioButton统一事件处理 private void RadioButton_Group0_CheckedChanged(object sender, EventArgs e) { var radioButton = sender as RadioButton; if (radioButton == null || !radioButton.Checked) return; var parts = radioButton.Name.Split('_'); if (parts.Length < 3 || !int.TryParse(parts[1], out int baseNum) || !int.TryParse(parts[2], out int suffix)) { return; } int firstParam = baseNum + suffix - 1; UpdateTextBoxes(firstParam, groupBox_0); } // GroupBox1的RadioButton统一事件处理 private void RadioButton_Group1_CheckedChanged(object sender, EventArgs e) { var radioButton = sender as RadioButton; if (radioButton == null || !radioButton.Checked) return; var parts = radioButton.Name.Split('_'); if (parts.Length < 3 || !int.TryParse(parts[1], out int baseNum) || !int.TryParse(parts[2], out int suffix)) { return; } int firstParam = baseNum + suffix - 1; UpdateTextBoxes(firstParam, groupBox_1); }
方案3:使用数据绑定(面向对象风格)
定义ViewModel类,通过数据绑定关联控件,减少事件代码:
// 定义ViewModel public class DetailViewModel : INotifyPropertyChanged { private int _firstParam; public int FirstParam { get => _firstParam; set { _firstParam = value; OnPropertyChanged(); // 批量更新所有Detail属性 for (int i = 0; i <= 8; i++) { typeof(DetailViewModel).GetProperty($"Detail{i}")?.SetValue(this, MyCommands.GetDetailValue(value, i)); } } } public string Detail0 { get; set; } public string Detail1 { get; set; } // ... 依次定义Detail2到Detail8 public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } // 窗体初始化绑定 private DetailViewModel _group0ViewModel = new DetailViewModel(); private DetailViewModel _group1ViewModel = new DetailViewModel(); public YourForm() { InitializeComponent(); // GroupBox0的TextBox绑定 textBox_5_0.DataBindings.Add(nameof(TextBox.Text), _group0ViewModel, nameof(DetailViewModel.Detail0)); textBox_5_1.DataBindings.Add(nameof(TextBox.Text), _group0ViewModel, nameof(DetailViewModel.Detail1)); // ... 绑定剩余textBox_5_*控件 // GroupBox1的TextBox绑定 textBox_19_0.DataBindings.Add(nameof(TextBox.Text), _group1ViewModel, nameof(DetailViewModel.Detail0)); textBox_19_1.DataBindings.Add(nameof(TextBox.Text), _group1ViewModel, nameof(DetailViewModel.Detail1)); // ... 绑定剩余textBox_19_*控件 } // RadioButton事件处理示例 private void radioButton_5_1_CheckedChanged(object sender, EventArgs e) { if ((sender as RadioButton)?.Checked == true) _group0ViewModel.FirstParam = 5; } private void radioButton_5_2_CheckedChanged(object sender, EventArgs e) { if ((sender as RadioButton)?.Checked == true) _group0ViewModel.FirstParam = 6; } // ... 其他RadioButton只需设置对应的FirstParam值
内容的提问来源于stack exchange,提问作者faugustom
相关产品推荐
相关产品推荐

