【问题标题】:how to dynamically add combobox in windows forms(C#) and bound it to a column of a table in sql database如何在 Windows 窗体(C#)中动态添加组合框并将其绑定到 sql 数据库中表的列
【发布时间】:2010-01-28 06:26:39
【问题描述】:

我的 windows 窗体有一个添加按钮,每次单击后都会在窗体中添加一个组合框。问题是,我无法在运行时将其绑定到表列。使用现有数据绑定源会在所有组合框中选择相同的值。我正在用 C# 编写代码

这里是示例代码:

ComboBox ocbNext = new ComboBox();
//HAVE set the rest of the properties right, the problem is with the databinding
ocbNext.DataSource = this.dummysubjectBindingSource;
ocbNext.DisplayMember = "sub_name";
ocbNext.ValueMember = "sub_name";
this.Controls.Add(ocbNext);

【问题讨论】:

  • 看起来您已经回答了问题的第一部分。对于第二部分,它应该很容易实现。让我们看看你到目前为止得到了什么......
  • 嘿,问题出在 ocbNext.DataSource = this.dummysubjectBindingSource;它与我为静态存在的组合框添加的数据绑定源相同,当我为动态添加的组合框使用相同的数据绑定源时,问题就开始了。初始数据绑定源是通过向导添加的...我不知道如何动态添加一个

标签: c# .net winforms combobox


【解决方案1】:

我在解决方案中添加了一个 DataSet,并在设计器中删除了 Employees 表(来自 Northwind),它自动创建了 employeesBindingSource。我在表单上放置了一个组合框和一个按钮,并设置了组合的 DataSourceDataMember。然后我处理了一些事件:

    private void Form1_Load(object sender, EventArgs e)
    {
        this.employeesTableAdapter.Fill(this.dS.Employees);
    }

    private int _i = 0;
    private void button1_Click(object sender, EventArgs e)
    {
        ComboBox combo = new ComboBox();
        combo.DataSource = this.employeesBindingSource;
        combo.DisplayMember = this.dS.Tables[0].Columns[++_i].ColumnName;
        combo.Location = new Point(comboBox1.Location.X, comboBox1.Location.Y + comboBox1.Height * _i);
        this.Controls.Add(combo);
    }

因此,在每次点击时,都会在表单上动态添加一个新的组合,就在前一个组合的正下方。该组合还绑定到Employees 表中的下一列(但是没有边界检查)。

如您所见,这是非常简单的事情。希望这可以帮助。


好的,这是代码的变体,可以帮助您解决您在此答案的 cmets 中提出的其他问题。

假设您有一个带有按钮的Form 和一个带有Employees 表的DataSet。单击按钮时,它会创建一个组合,并用数据填充它(EmployeesName 列)。每次添加一个组合时,它都会获得自己的数据副本(这对于能够一次从一个组合中删除项目很重要)。然后,每次您在组合中选择一个值时,该组合都会被禁用,并且其他组合在其列表中没有该选定值。

  private int _i = 0;
    private void button1_Click(object sender, EventArgs e)
    {
        DataSet dataS = dS.Clone();
        this.employeesTableAdapter.Fill((DS.EmployeesDataTable)dataS.Tables[0]);
        BindingSource bindSource = new BindingSource(dataS, "Employees");

        ComboBox combo = new ComboBox();
        combo.Name = this.dS.Tables[0].Columns[0].ColumnName + (++_i).ToString();
        combo.DataSource = bindSource;
        combo.DisplayMember =  this.dS.Tables[0].Columns[1].ColumnName; //This column is the Name of Employee
        combo.Location = new Point(button1.Location.X, button1.Location.Y + combo.Height * _i);
        combo.SelectedIndexChanged += new EventHandler(comboBox_SelectedIndexChanged);
        this.Controls.Add(combo);
    }

    private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
    {
        foreach (Control ctrl in this.Controls)
        {
            if (ctrl is ComboBox && ctrl != sender && ctrl.Enabled)
            {
                ((BindingSource)((ComboBox)ctrl).DataSource).RemoveAt(((ComboBox)sender).SelectedIndex);
            }
        }
        ((ComboBox)sender).Enabled = false;
    }

这非常接近您的要求,或者很容易适应您的期望。享受并请选择一个答案作为接受的答案。谢谢!

【讨论】:

  • thnx tzup...它真的很简单,它是 hlpd。你请让我知道硬件以确保用户为每个组合框选择不同的值吗?我的意思是有没有办法禁用已经选择的值???
  • 嗨,Raghav,请看我回答的第二部分。
【解决方案2】:

选项 1:用字符串填充组合框:

this.comboBox1.Items.Add("Syed");
this.comboBox1.Items.Add("Baqar");

选项 2:用字符串数组填充组合框:

this.comboBox1.Items.AddRange(new object[] { "Syed", "Baqar" });

【讨论】:

    【解决方案3】:

    需要先给父窗口添加控件,再设置数据源。

    ComboBox ocbNext = new ComboBox();
    this.Controls.Add(ocbNext);
    ocbNext.DisplayMember = "sub_name";
    ocbNext.ValueMember = "sub_name";
    ocbNext.DataSource = this.dummysubjectBindingSource;
    

    【讨论】:

      【解决方案4】:

      如果在clickevent中创建一个新的本地ComboBox变量应该没问题。如果您为 ComboBox 使用全局变量,这可能会解释您的问题。但是如果没有样本,你很难看到实际发生了什么,所以认为这只是一个粗略的猜测

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-27
        • 1970-01-01
        • 2021-05-10
        • 1970-01-01
        • 2014-03-27
        • 2016-10-18
        相关资源
        最近更新 更多