【问题标题】:cascading comboBox in windows form using c#使用c#在windows窗体中级联comboBox
【发布时间】:2015-01-29 14:31:05
【问题描述】:

我正在尝试在 windows 窗体应用程序中从同一个表更改的 combobox1 selectedText 上填充 Combobox2。我正在使用 sql serevr 2008 数据库。我无法在组合框选定的文本上填充组合框 2 已更改。

这是我尝试过的:

private void Purchase_Load(object sender, EventArgs e)
    {
        fillName();
        comboBoxName.SelectedIndex = -1;

    }

   private void comboBoxName_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (comboBoxName.SelectedText != "")
        {
            fillMake();
        }


    }

   private void fillName()
   {
       SqlConnection con = new SqlConnection(@"Data Source=ashish-pc\;Initial Catalog=HMS;Integrated Security=True");
       con.Open();
       string str = "Select Item_Name from Item";
       SqlCommand cmd = new SqlCommand(str, con);
       SqlDataAdapter adp = new SqlDataAdapter(str, con);
       DataTable dtItem = new DataTable();
       adp.Fill(dtItem);
       cmd.ExecuteNonQuery();
       comboBoxName.DataSource = dtItem;
       comboBoxName.DisplayMember = "Item_Name";
       comboBoxName.ValueMember = "Item_Make";


   }
    private void fillMake()
    {
        SqlConnection con = new SqlConnection(@"Data Source=ashish-pc\;Initial Catalog=HMS;Integrated Security=True");
        con.Open();
        string str = "Select Item_Make from Item Where Item_Name='" + comboBoxName.SelectedText + "'";
        SqlCommand cmd = new SqlCommand(str, con);
        SqlDataAdapter adp = new SqlDataAdapter(str, con);
        DataTable dtItem = new DataTable();
        adp.Fill(dtItem);
        cmd.ExecuteNonQuery();
        comboBoxName.DataSource = dtItem;
        comboBoxName.DisplayMember = "Item_Make";
        comboBoxName.ValueMember = "Item_Name";
        comboBoxName.SelectedIndex = -1;
        comboBoxName.Text = "Select";
    }

Items 的 Sql 服务器表

Item_Code  Item_Name  Item_Make Item_Price UnitofMeasurement

           Cable        anchor  45.0000       meter
           Cable        polycab 30.0000       meter
           Button       anchor  15.0000       unit
           Button       havells 20.0000       unit
           Switch       cona    70.0000       unit

我已经寻找解决方案,但很不幸。 请帮帮我。 提前致谢。

【问题讨论】:

  • 旁注:请使用SqlParameters来防止Sql注入。
  • 感谢sybren的建议,我会记住的。
  • 在 fillName 中,您没有选择 Item_Make。您还应该更详细地描述什么不起作用。
  • 老实说只是随便说你会记住参数是不够的。像这样创建通过 sql 是犯罪行为。您必须使用参数或更好的存储过程。
  • ROFL。当然,如果你在你的过程中放了一堆动态 sql,你就达不到目的了。真正的关键是,当它是一个文本框时,编码风格可以并且将会被复制。始终以正确的方式进行操作,可以省去很多麻烦。另外,当您转换为过程时,您可以在 sql 端修复错误,而无需重新部署应用程序。分层您的应用程序让您的生活变得如此轻松。

标签: c# sql-server winforms


【解决方案1】:

要弄清楚您要做什么有点困难,但听起来您正在尝试填充第二个组合框 (comboBoxMake?),具体取决于在 comboBoxName 中选择的内容。我是根据这个假设来回答这个问题的。抱歉,如果我有这个错误。

这段代码中有很多需要注意的地方。我们先看fillName()

   private void fillName()
   {
       SqlConnection con = new SqlConnection(@"Data Source=ashish-pc\;Initial Catalog=HMS;Integrated Security=True");
       con.Open();
       string str = "Select Item_Name from Item";
       SqlCommand cmd = new SqlCommand(str, con);
       SqlDataAdapter adp = new SqlDataAdapter(str, con);
       DataTable dtItem = new DataTable();
       adp.Fill(dtItem);
       cmd.ExecuteNonQuery();
       comboBoxName.DataSource = dtItem;
       comboBoxName.DisplayMember = "Item_Name";
       comboBoxName.ValueMember = "Item_Make";
   }

您需要Dispose() 您的数据库对象。这可以通过 using { .. } 块非常干净地完成。

您无需手动打开连接;用数据适配器填充表格 自动执行此操作。

您不需要致电ExecuteNonQuery()

您应该使用带有命令对象的SqlDataAdapter 构造函数重载,因为您已经手动创建了命令。

最后,基于我对您目标的假设,我在您的查询中添加了一个distinct,因此它只会获得唯一的Item_Names。

private void fillName()
{
    string str = "Select distinct Item_Name from Item";
    using (SqlConnection con = new SqlConnection(@"Data Source=ashish-pc\;Initial Catalog=HMS;Integrated Security=True"))
    {
        using (SqlCommand cmd = new SqlCommand(str, con))
        {
            using (SqlDataAdapter adp = new SqlDataAdapter(cmd))
            {
                DataTable dtItem = new DataTable();
                adp.Fill(dtItem);
                comboBoxName.DataSource = dtItem;
                comboBoxName.DisplayMember = "Item_Name";
                comboBoxName.ValueMember = "Item_Name";
            }
        }
    }
}

转到fillMake()。我上面提到的同样的建议也适用。另外:

参数化你的 SQL。 参数化您的 SQL。这不仅比将 SQL 连接在一起要安全得多,而且要干净得多。认真阅读一下 SQL 注入:http://en.wikipedia.org/wiki/SQL_injection

您原始帖子中的fillMake() 方法似乎正在重新填充comboBoxName。它是否正确?您提到了两个组合框,但您的代码仅引用了一个。我假设您的意思是在此处填充另一个组合框 (comboBoxMake?):

private void fillMake()
{
    string str = "Select Item_Make from Item Where Item_Name = @item_name";
    using (SqlConnection con = new SqlConnection(@"Data Source=ashish-pc\;Initial Catalog=HMS;Integrated Security=True"))
    {
        using (SqlCommand cmd = new SqlCommand(str, con))
        {
            cmd.Parameters.AddWithValue("@item_name", comboBoxName.Text);
            using (SqlDataAdapter adp = new SqlDataAdapter(cmd))
            {
                DataTable dtItem = new DataTable();
                adp.Fill(dtItem);
                comboBoxMake.DataSource = dtItem;
                comboBoxMake.DisplayMember = "Item_Make";
                comboBoxMake.ValueMember = "Item_Make";
                comboBoxMake.SelectedIndex = -1;
                comboBoxMake.Text = "Select";
            }
        }
    }
}

最后,更改事件处理程序中的代码,使其查看Text 而不是SelectedText 属性:

private void comboBoxName_SelectedIndexChanged(object sender, EventArgs e)
{
    if (!string.IsNullOrEmpty(comboBoxName.Text))  // Text instead of SelectedText
    {
        fillMake();
    }
}

【讨论】:

  • 非常感谢 Slippery Pete 提供的解决方案。但它仍然没有填充或填充第二个组合框。请帮忙!
  • @user2042290 请显示来自Item 表的一些示例数据。
  • 我已经编辑了问题,附上了“项目”的表格
  • @user2042290 谢谢,你的数据和我想象的一样。我已将答案更新为comboBoxName_SelectedIndexChanged
  • 感谢小伙伴的帮助,我把Item_Name的SelectedIndexChanged事件删掉了,改写一下就可以了。再次非常感谢您
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-11
  • 2012-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多