简体   繁体   English

WinForms comboBox_SelectedValueChanged在tabControl_SelectedIndexChanged上触发了三次

[英]WinForms comboBox_SelectedValueChanged fired thrice on tabControl_SelectedIndexChanged

I have a tabcontrol element with multiple tabs. 我有一个带有多个标签的tabcontrol元素。 On tab 2 (index 1) I have a combobox that manages a template selection. 在选项卡2(索引1)上,我有一个组合框来管理模板选择。 The template object itself holds an ID and a name 模板对象本身包含一个ID和一个名称

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. 使用此组合框,我想显示名称并选择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. 运行项目并选择第二个选项卡时, comboBox1_SelectedValueChanged触发3次。

On the first and second run cmbx.SelectedTemplateID returns me the selected template ID 1. This is correct. 在第一次和第二次运行时, cmbx.SelectedTemplateID我返回所选模板cmbx.SelectedTemplateID 。这是正确的。

The third run returns me a null pointer. 第三次运行返回空指针。

Why does it fire 3 times? 为什么会发射3次? And why does the third event call return a null pointer? 为什么第三个事件调用返回空指针?

I will try to answer it on my own. 我将尝试自己回答。 I removed 我删除了

cmbx.DataSource = null;
cmbx.Items.Clear();

and

cmbx.ValueMember = nameof(Template.ID);

Further I changed the binding order 此外,我更改了绑定顺序

BindingSource bindingSource = new BindingSource();
bindingSource.DataSource = templates;

cmbx.DisplayMember = nameof(CoBRATemplate.Name);

cmbx.DataSource = bindingSource.DataSource;

This works for me. 这对我有用。 But please feel free to provide a "better" answer. 但请随时提供“更好”的答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM