WinConms comboBox_SelectedValueChanged在tabControl_SelectedIndexChanged上触发三次 [英] WinForms comboBox_SelectedValueChanged fired thrice on tabControl_SelectedIndexChanged

查看:121
本文介绍了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}");
}
}




$


和我的组合框类< br $>


 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 id

So 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上触发三次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆