本文介绍了WinConms comboBox_SelectedValueChanged在tabControl_SelectedIndexChanged上触发三次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我有一个带有多个标签的tabcontrol元素。在选项卡2(索引1)上,我有一个管理模板选择的组合框。模板对象本身包含ID和名称 内部类模板 { public Template(double id,string name) { ID = id; 姓名=姓名; } 公共双重身份证{get;私人集; } public string Name {get;私人集; } } $ 使用这个组合框,我想显示名称并选择ID。我将提供一个完整的工作示例。 我的表格 public partial class Form1:Form { public Form1() { InitializeComponent(); cmbx = new Cmbx(comboBox1); //传入组合框元素} 私人Cmbx cmbx; //我的组合框类 private void tabControl1_SelectedIndexChanged(object sender,EventArgs e) { if(tabControl1.SelectedIndex == 1)// tab 2是否有效? { cmbx.CreateTemplateSelection(myTemplates); // init组合框与模板列表} } private void comboBox1_SelectedValueChanged(object sender,EventArgs e) { //处理新的这里选择的ID MessageBox.Show($" Combobox Change Event - Selected ID {cmbx.SelectedTemplateID}"); } } $ 和我的组合框类 class Cmbx { public Cmbx(ComboBox cmbx) { this .cmbx = cmbx; } 私人ComboBox cmbx; // GUI元素 private Template [] currentTemplates; public double SelectedTemplateID //获取当前选定的值 { get { Template templateInfo = cmbx.SelectedValue as Template; 返回templateInfo.ID; } } public void CreateTemplateSelection(Template [] templates)//填充组合框 { if(currentTemplates!= null)//第一次? { if(currentTemplates.SequenceEqual(templates))//不同的数据? { return; //没有改变 - >返回} } //不同数据 cmbx.DataSource = null; //清除组合框 cmbx.Items.Clear(); BindingSource bindingSource = new BindingSource(); bindingSource.DataSource = templates; cmbx.DataSource = bindingSource.DataSource; //设置数据 cmbx.DisplayMember = nameof(Template.Name); //显示模板名称 cmbx.ValueMember = nameof(Template.ID); //选择模板ID bool valid = templates.Length> 0; //现有数据? if(valid&& cmbx.SelectedIndex!= 0) cmbx.SelectedIndex = 0; //选择第一项 currentTemplates = templates; //将新模板分配给当前的模板} } 当运行项目并选择第二个选项卡时,`comboBox1_SelectedValueChanged`将触发3次。 在第一次和第二次运行时`cmbx.SelectedTemplateID`返回我选择的模板ID 1.这是正确的。 第三次运行会返回一个空指针。 为什么会发射3次?为什么第三个事件调用返回一个空指针?解决方案 >>为什么会激发3次? "SelectedValueChanged""设置其DataSource,DisplayMember或ValueMember时将触发combox事件。 cmbx.DataSource = bindingSource.DataSource; //设置数据 cmbx.DisplayMember = nameof(Template.Name); //显示模板名称 cmbx.ValueMember = nameof(Template.ID); //选择模板ID 因此,当执行上面的代码时,"comboBox1_SelectedValueChanged"将被触发。 >>为什么第三个事件调用返回一个空指针? 通过在get访问器的前面设置一个断点方法"SelectedTemplateID",你可以看到当"comboBox1_SelectedValueChanged"时第三次执行"cmbx.SelectedValue"。获取单个值而不是类型为"模板"的对象的。因此无法将其转换为模板类型会导致错误。 为了解决此问题,您可以参考以下步骤。 I have a tabcontrol element with multiple tabs. On tab 2 (index 1) I have a combobox that manages a template selection. The template object itself holds an ID and a name internal class Template { public Template(double id, string name) { ID = id; Name = name; } public double ID { get; private set; } public string Name { get; private set; } }With this combobox I want to display the name and select the ID. I will provide a full working example.My form public partial class Form1 : Form { public Form1() { InitializeComponent(); cmbx = new Cmbx(comboBox1); // pass in the combobox element } private Cmbx cmbx; // My combobox class private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) { if (tabControl1.SelectedIndex == 1) // tab 2 active? { cmbx.CreateTemplateSelection(myTemplates); // init combobox with the templates list } } private void comboBox1_SelectedValueChanged(object sender, EventArgs e) { // handle the new selected ID here MessageBox.Show($"Combobox Change Event - Selected ID {cmbx.SelectedTemplateID}"); } }and my combobox class class Cmbx { public Cmbx(ComboBox cmbx) { this.cmbx = cmbx; } private ComboBox cmbx; // GUI element private Template[] currentTemplates; public double SelectedTemplateID // Get the current selected value { get { Template templateInfo = cmbx.SelectedValue as Template; return templateInfo.ID; } } public void CreateTemplateSelection(Template[] templates) // populate the combobox { if (currentTemplates != null) // first time? { if (currentTemplates.SequenceEqual(templates)) // different data? { return; // nothing changed -> return } } // different data cmbx.DataSource = null; // clear the combobox cmbx.Items.Clear(); BindingSource bindingSource = new BindingSource(); bindingSource.DataSource = templates; cmbx.DataSource = bindingSource.DataSource; // setup the data cmbx.DisplayMember = nameof(Template.Name); // display the template name cmbx.ValueMember = nameof(Template.ID); // select the template id bool valid = templates.Length > 0; // existing data? if (valid && cmbx.SelectedIndex != 0) cmbx.SelectedIndex = 0; // select the first item currentTemplates = templates; // assign the new templates to the current ones } }When running the project and selecting the second tab the `comboBox1_SelectedValueChanged` fires 3 times.On the first and second run `cmbx.SelectedTemplateID` returns me the selected template ID 1. This is correct.The third run returns me a null pointer.Why does it fire 3 times? And why does the third event call return a null pointer? 解决方案 Hi,>> Why does it fire 3 times?The "SelectedValueChanged" event of combox will be triggered when setting its DataSource, DisplayMember or ValueMember. cmbx.DataSource = bindingSource.DataSource; // setup the data cmbx.DisplayMember = nameof(Template.Name); // display the template name cmbx.ValueMember = nameof(Template.ID); // select the template idSo when executing the above code, the "comboBox1_SelectedValueChanged" will be triggered.>> And why does the third event call return a null pointer?By setting a breakpoint in the front of the get accessor of method "SelectedTemplateID", you can see that when "comboBox1_SelectedValueChanged" is executed for the third time, "cmbx.SelectedValue" gets a single value instead of an object of type "Template". So the inability to convert it to a Template type caused an error.In order to solve this problem, you can refer to the following steps. 这篇关于WinConms comboBox_SelectedValueChanged在tabControl_SelectedIndexChanged上触发三次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 09-12 13:12