【问题标题】:Add row to WinForms combobox after populating it from a datatable从数据表中填充行后,将行添加到 WinForms 组合框
【发布时间】:2020-03-18 20:52:11
【问题描述】:

我正在使用以下代码从数据表中填充一个组合框:

public void PopulateCategoryCbo()
{
    string connString = string.Format(<connectionString>);
    NpgsqlConnection conn = new NpgsqlConnection(connString);
    conn.Open();

    string query = "SELECT id, category FROM categories ORDER BY category";
    NpgsqlCommand cmd = new NpgsqlCommand(query, conn);

    NpgsqlDataReader reader;
    reader = cmd.ExecuteReader();

    DataTable dt = new DataTable();
    //DataRow row = dt.NewRow();
    //row["id"] = 0;
    //row["category"] = "All Categories";
    //dt.Rows.InsertAt(row, 0);

    dt.Columns.Add("id", typeof(string));
    dt.Columns.Add("category", typeof(string));
    dt.Load(reader);

    cboSelectCategory.ValueMember = "id";
    cboSelectCategory.DisplayMember = "category";
    cboSelectCategory.DataSource = dt;

    conn.Close();
}

四行注释是我尝试在数据表顶部添加索引为 0 的“所有类别”行。我按照this SO question and answer 执行了该代码。

但是,当我运行该解决方案时,它会在 row["id"] = 0; 行中断,并显示消息“列“id”不属于表。'

我尝试使用 0 和 1,以为它们会引用列的索引值,但我收到消息“列 0 不属于表。”

我不明白为什么这不起作用。当我在谷歌上搜索这个问题时,我看到了很多类似的解决方案。

【问题讨论】:

  • 在您的dt.Load(reader);之后运行您的注释代码。
  • @LarsTech - 将代码移到 dt.Load(reader); 之后就可以了。再次感谢!

标签: c# winforms datatable combobox datarow


【解决方案1】:

不是原始问题的答案,但通过以下方法,您将消除主要问题。

对于组合框的数据源,你不需要繁重的DataTable,而是使用普通的c#对象

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
}

然后将数据库中的数据加载到Category对象列表中

private List<Category> LoadCategories()
{
    var query = "SELECT id, category FROM categories ORDER BY category";
    using (var connection = new NpgsqlConnection(connString))
    using (var command = new NpgsqlCommand(query, connection))
    {
        conn.Open();
        var categories = new List<Category>();
        using (var reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                var category = new Category()
                {
                    Id = reader.GetInt32(0),
                    Name = reader.GetString(1)
                }
                categories.Add(category);
            }
        }

        return categories;
    }
}

那么用法就变得很简单了

var categories = LoadCategories();

var all = new Category { Id = 0, Name = "All Categories" };
categories.Insert(0, all);

cboSelectCategory.ValueMember = "Id";
cboSelectCategory.DisplayMember = "Name";
cboSelectCategory.DataSource = categories;

【讨论】:

  • 这是 OOP 的一个方面,我非常缺乏这方面的知识和经验。谢谢,Fabio!
【解决方案2】:

您正在向 dt 添加一行,这是一个没有列的新 DataTable。如果要填充 DataTable,请查看 DbDataAdapter.Fill 而不是 DbDataReader。填写 DataTable,然后添加您的行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    相关资源
    最近更新 更多