如何在C# WinForm中根据ComboBoxA选择切换ComboBoxB数据源
动态ComboBox联动:解决SelectionChanged事件中无法访问另一个动态创建ComboBox的问题
我通过代码在WPF窗体中动态添加了两个ComboBox,需求是根据ComboBoxA的选择切换ComboBoxB的数据源:默认ComboBoxB使用itemsource_1,当ComboBoxA选中"4"时,ComboBoxB的数据源切换为itemsource_4。已为ComboBoxA添加SelectionChanged事件处理程序,但无法在事件中访问ComboBoxB,求解决办法。
相关代码片段
动态添加ComboBox的代码
string[] comboboxAitemsource = { "1", "2", "3", "4"}; string[] itemsource_1 = { "11", "12", "13", "14"}; string[] itemsource_2 = { "21", "22", "23", "24"}; string[] itemsource_3 = { "31", "32", "33", "34"}; string[] itemsource_4 = { "41", "42", "43", "44"}; int left_margin = 10, top_margin = margin, margin_inc = 40, sec_left_margin = 300; System.Windows.Controls.Label ComboboxAlabel = new System.Windows.Controls.Label(); ComboboxAlabel.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; ; ComboboxAlabel.VerticalAlignment = VerticalAlignment.Top; ComboboxAlabel.Name = "typeComboboxAlabel"; ComboboxAlabel.Content = "COMBOBOX A"; ComboboxAlabel.Height = 40; ComboboxAlabel.Margin = new Thickness((double)left_margin, (double)top_margin, (double)10, (double)0); grid.Children.Add(ComboboxAlabel); System.Windows.Controls.ComboBox comboboxA = new System.Windows.Controls.ComboBox(); comboboxA.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; ; comboboxA.VerticalAlignment = VerticalAlignment.Top; comboboxA.Name = "typeCombobox"; comboboxA.Height = 20; comboboxA.Width = 250; comboboxA.Margin = new Thickness((double)sec_left_margin, (double)top_margin, (double)10, (double)0); comboboxA.ItemsSource = comboboxAitemsource; comboboxA.SelectedIndex = 0; comboboxA.SelectionChanged += new System.Windows.Controls.SelectionChangedEventHandler(typeCombobox_SelectionChangedEventHandler); top_margin = top_margin + margin_inc; grid.Children.Add(comboboxA); System.Windows.Controls.Label comboboxBlabel = new System.Windows.Controls.Label(); comboboxBlabel.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; comboboxBlabel.VerticalAlignment = VerticalAlignment.Top; comboboxBlabel.Name = "typeLabelUpdate"; comboboxBlabel.Content = "COMBOBOX B"; comboboxBlabel.Height = 40; comboboxBlabel.Margin = new Thickness((double)left_margin, (double)top_margin, (double)10, (double)0); grid.Children.Add(comboboxBlabel); System.Windows.Controls.ComboBox comboboxB = new System.Windows.Controls.ComboBox(); comboboxB.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; comboboxB.VerticalAlignment = VerticalAlignment.Top; comboboxB.Name = "typeComboBoxUpdate"; comboboxB.Height = 20; comboboxB.Width = 250; comboboxB.Margin = new Thickness((double)sec_left_margin, (double)top_margin, (double)10, (double)0); comboboxB.ItemsSource = itemsource_1; comboboxB.SelectedIndex = 0; top_margin = top_margin + margin_inc; grid.Children.Add(comboboxB);
ComboBoxA的事件处理程序
private void typeCombobox_SelectionChangedEventHandler(object sender, EventArgs e) { ComboBox comboBox = (ComboBox)sender; }
解决办法
方法1:将ComboBoxB声明为类级成员变量
在窗体类中定义一个成员变量存储ComboBoxB,这样事件处理程序可以直接访问它。
- 在窗体类的顶部添加成员变量:
private ComboBox _comboboxB;
- 在动态创建ComboBoxB时,将实例赋值给该成员变量:
// 创建comboboxB的代码... _comboboxB = comboboxB; // 赋值给类成员变量 grid.Children.Add(comboboxB);
- 修改事件处理程序:
private void typeCombobox_SelectionChangedEventHandler(object sender, SelectionChangedEventArgs e) { ComboBox comboBoxA = (ComboBox)sender; string selectedValue = comboBoxA.SelectedItem.ToString(); // 根据选中值切换ComboBoxB的数据源 switch(selectedValue) { case "1": _comboboxB.ItemsSource = itemsource_1; break; case "2": _comboboxB.ItemsSource = itemsource_2; break; case "3": _comboboxB.ItemsSource = itemsource_3; break; case "4": _comboboxB.ItemsSource = itemsource_4; break; } _comboboxB.SelectedIndex = 0; // 重置默认选中项 }
方法2:通过容器的Children集合查找ComboBoxB
如果不想使用类成员变量,可以通过控件容器(这里是grid)的Children集合,根据控件名称查找ComboBoxB。
注意:需要引入
System.Linq命名空间才能使用OfType和FirstOrDefault方法。
修改事件处理程序:
using System.Linq; // ... private void typeCombobox_SelectionChangedEventHandler(object sender, SelectionChangedEventArgs e) { ComboBox comboBoxA = (ComboBox)sender; string selectedValue = comboBoxA.SelectedItem.ToString(); // 从grid中查找名为"typeComboBoxUpdate"的ComboBox ComboBox comboBoxB = grid.Children.OfType<ComboBox>() .FirstOrDefault(cb => cb.Name == "typeComboBoxUpdate"); if(comboBoxB != null) { switch(selectedValue) { case "1": comboBoxB.ItemsSource = itemsource_1; break; case "2": comboBoxB.ItemsSource = itemsource_2; break; case "3": comboBoxB.ItemsSource = itemsource_3; break; case "4": comboBoxB.ItemsSource = itemsource_4; break; } comboBoxB.SelectedIndex = 0; } }
方法3:利用Tag属性传递ComboBoxB
在绑定ComboBoxA的事件时,将ComboBoxB赋值给ComboBoxA的Tag属性,这样在事件处理程序中可以直接从sender的Tag中获取ComboBoxB。
- 修改ComboBoxA的创建代码,添加Tag赋值:
comboboxA.Tag = comboboxB; // 将comboboxB绑定到comboboxA的Tag属性 comboboxA.SelectionChanged += typeCombobox_SelectionChangedEventHandler;
- 修改事件处理程序:
private void typeCombobox_SelectionChangedEventHandler(object sender, SelectionChangedEventArgs e) { ComboBox comboBoxA = (ComboBox)sender; // 从Tag中获取ComboBoxB实例 ComboBox comboBoxB = comboBoxA.Tag as ComboBox; if(comboBoxB != null) { string selectedValue = comboBoxA.SelectedItem.ToString(); switch(selectedValue) { case "1": comboBoxB.ItemsSource = itemsource_1; break; case "2": comboBoxB.ItemsSource = itemsource_2; break; case "3": comboBoxB.ItemsSource = itemsource_3; break; case "4": comboBoxB.ItemsSource = itemsource_4; break; } comboBoxB.SelectedIndex = 0; } }
内容的提问来源于stack exchange,提问作者DeLorean
相关产品推荐
相关产品推荐

