C#从数据库中的表填充ComboBox

我有一个名为combobox1 ,我想用id作为值和Name作为显示名称来填充它。 我搜索并阅读了一些教程,发现此代码在Form加载事件中使用,但它没有填充列表。 我看到一个空的下拉列表。 我错在哪里的想法?

在我的数据库类中,我有这个function。

 public static void FillDropDownList(string Query, System.Windows.Forms.ComboBox DropDownName) { SqlDataReader dr; SqlConnection myConnection = new SqlConnection(CONNECTION_STRING); try { myConnection.Open(); } catch (Exception e) { Console.WriteLine(e.ToString()); } // Check whether the Drop Down has existing items. If YES, empty it. if (DropDownName.Items.Count > 0) DropDownName.Items.Clear(); SqlCommand cmd = new SqlCommand(Query, myConnection); dr = cmd.ExecuteReader(); while (dr.Read()) DropDownName.Items.Add(dr[0].ToString()); Console.Write(DropDownName.Items.Add(dr[0].ToString())); dr.Close(); } 

在我的forms我称之为

 private void sales_record_Load(object sender, EventArgs e) { SqlConnection con = new SqlConnection(DBUtils.CONNECTION_STRING); DBUtils.FillDropDownList("select id,Name from Farms", comboBox1); } 

我的建议 – 尽可能使用.NET内置function,不要手动处理数据绑定(这是你在代码中尝试做的事情):

  1. 使用ExecuteQuery从数据库中提取DataTable。
  2. 设置DropDownName.DataSource = yourDataTable。
  3. 设置DropDownName.ValueMember =“id”。
  4. 设置DropDownName.DisplayMember =“名称”。

所以你的代码看起来类似于:

 public static void FillDropDownList(string Query, System.Windows.Forms.ComboBox DropDownName) { DataTable dt; using (var cn = new SqlConnection(CONNECTION_STRING)) { cn.Open(); try { SqlCommand cmd = new SqlCommand(Query, cn); dt = cmd.ExecuteQuery(); } catch (SqlException e) { Console.WriteLine(e.ToString()); return; } } DropDownName.DataSource = dt; DropDownName.ValueMember = "id"; DropDownName.DisplayMember = "Name"; } 

请注意我如何将exception类型更改为SqlException ,因此我们只查找数据库错误。 其他一切都会爆炸。 myConnection.Open();我不记得任何情况 会抛出一个exception,所以你的try块不是很有用。 请注意我的try子句 – 它里面有ExecuteQuery ,很可能会失败。

编辑: 使用using构造时,不需要在finally块中关闭连接 。 因此它可以被删除 – 结果你的代码变得更加紧凑。

这应该做你想要的。 从设计的角度来看,我看到的问题是,为此编码查询的任何人都需要知道返回的前两列需要分别反映ID和显示项。 除此之外,实际的列名称无关紧要,因为ValueMember和DisplayMember属性(DataSource中每个相应列的字符串名称)是通过对[0]和Column [1]的顺序引用获得的。

请注意,我已经使用块包装了每个DataAccess对象(SQLConnection实例和SQLCommand实例。这是数据访问对象的推荐做法,它倾向于使用非托管资源并需要处理。使用块处理每个对象。请注意,每个使用块都包含自己的范围。

希望有所帮助!

更新:@Neolisk在我写作时发布了他的答案。 虽然它们不是重复的,但它们涵盖了许多相同的基础。 在他的答案与此之间,你应该拥有你需要的东西!

 public void FillDropDownList(string Query, ComboBox DropDownName) { // If you use a DataTable (or any object which implmenets IEnumerable) // you can bind the results of your query directly as the // datasource for the ComboBox. DataTable dt = new DataTable(); // Where possible, use the using block for data access. The // using block handles disposal of resources and connection // cleanup for you: using (var cn = new SqlConnection(CONNECTION_STRING)) { using(var cmd = new SqlCommand(Query, cn)) { cn.Open(); try { dt.Load(cmd.ExecuteReader()); } catch (SqlException e) { // Do some logging or something. MessageBox.Show("There was an error accessing your data. DETAIL: " + e.ToString()); } } } DropDownName.DataSource = dt; DropDownName.ValueMember = dt.Columns[0].ColumnName; DropDownName.DisplayMember = dt.Columns[1].ColumnName; } 

我能够使用@Neolisk的代码使其工作。 仅对代码进行了一些小的更改,如下所示。

 public static void FillDropDownList(string Query, System.Windows.Forms.ComboBox DropDownName) { using (var cn = new SqlConnection(CONNECTION_STRING)) { cn.Open(); DataTable dt = new DataTable(); try { SqlCommand cmd = new SqlCommand(Query, cn); SqlDataReader myReader = cmd.ExecuteReader(); dt.Load(myReader); } catch (SqlException e) { Console.WriteLine(e.ToString()); return; } DropDownName.DataSource = dt; DropDownName.ValueMember = "id"; DropDownName.DisplayMember = "Name"; } }