7

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

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

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();
}

在我的表格中,我称之为

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

3 回答 3

11

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

请注意,我已将每个 DataAccess 对象(SQLConnection 实例和 SQLCommand 实例包装在 using 块中。这是数据访问对象的推荐做法,这些对象往往会消耗非托管资源并需要处置。using 块处理处置每个对象都适合你。请注意,每个 using 块都包含自己的范围。

希望有帮助!

更新:@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;
}
于 2013-01-01T22:59:17.217 回答
8

我的建议 - 尽可能使用 .NET 内置功能,不要手动处理数据绑定(这是您在代码中尝试执行的操作):

  1. 使用 ExecuteQuery 从数据库中提取数据表。
  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";
}

请注意我如何将异常类型更改为SqlException,因此我们只查找数据库错误。其他一切都会爆炸。我不记得什么时候myConnection.Open();会抛出异常,所以你的 try 块不是很有用。请注意我的 try 子句 - 它ExecuteQuery在其中,这很可能会失败。

编辑:使用结构无需关闭finallyusing中的连接。所以它可以被删除 - 结果你的代码变得更加紧凑。

于 2013-01-01T22:35:13.550 回答
3

我能够使用@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";
            }


        }
于 2013-01-02T07:38:38.660 回答