如何创建一种可以一次填充多个组合框的方法?

时间:2021-05-09 08:20:59

标签: c# winforms combobox ado.net lookup-tables

我正在用 C# 制作一个 windows 窗体应用程序。在应用程序中,我有一个名为 category page 的页面,其中插入了类别。我想在另一个页面中使用这些类别。所以我写了一个名为 fillCombo() 的方法,它在另一个页面的组合框中生成插入的类别。现在我在该页面中有另一个组合框,我也想要相同的功能。我怎样才能做到这一点?我可以制作一个将在方法中传递的组合框变量吗?这个问题的解决方案是什么?

private void fillCombo()
{
    Con.Open(); 
    SqlCommand cmd = new SqlCommand("select CatName from CategoryTbl", Con);
    SqlDataReader rdr;
    rdr = cmd.ExecuteReader();
    DataTable dt = new DataTable();
    dt.Columns.Add("CatName", typeof(string));
    dt.Load(rdr);
    CatCb.ValueMember = "catName";
    CatCb.DataSource = dt;
    Con.Close();
}

1 个答案:

答案 0 :(得分:1)

我们可以像这样将控件作为方法参数传递:

private void FillComboBox(ComboBox combobox)
{
  if ( combobox == null ) return; // Or throw new Exception...
  Con.Open();
  SqlCommand cmd = new SqlCommand("select CatName from CategoryTbl", Con);
  SqlDataReader rdr;
  rdr = cmd.ExecuteReader();
  DataTable dt = new DataTable();
  dt.Columns.Add("CatName", typeof(string));
  dt.Load(rdr);
  combobox.ValueMember = "catName";
  combobox.DataSource = dt;
  Con.Close();
}

我们这样称呼:

FillComboBox(myComboBox);

因此,我们可以根据所提供代码的逻辑填充我们想要的任何组合,拥有自己的数据源到自己的数据表。

可以改进和重构不执行查询并为每个组合创建一个表:

private const string CategoryColumnName = "CatName";

private DataTable CategoryLookupTable = new DataTable();

private void InitializeCategoryLookupTable()
{
  if ( Connection == null ) return; // Or throw new Exception...
  Connection.Open();
  try
  {
    using ( var command = new SqlCommand("select CatName from CategoryTbl", Connection) )
    using ( var reader = command.ExecuteReader() )
    {
      CategoryLookupTable.Columns.Add(CategoryColumnName, typeof(string));
      CategoryLookupTable.Load(reader);
    }
  }
  finally
  {
    Connection.Close();
  }
}

private void FillFromCategoryLookupTable(ComboBox combobox)
{
  if ( combobox == null ) return; // Or throw new Exception...
  if ( combobox.DataSource == CategoryLookupTable ) return;
  combobox.DataSource = null;
  combobox.ValueMember = CategoryColumnName;
  combobox.DataSource = CategoryLookupTable;
}

因此,我们将在某处(例如在 Form Load 或 Shown 事件处理程序中)调用 InitializeCategoryLookupTable,并且在任何调用 FillFromCategoryLookupTable 之前:

private void MyForm_Load(object sender, EventArgs e)
{
  InitializeCategoryLookupTable();
  FillFromCategoryLookupTable(myFirstComboBox);
}

如果需要不同的源和列名,可以通过将它们作为参数传递来以相同的方式完成重构:

private DataTable CreateLookupTable(string nameTable, string nameColumn)
{
  if ( Connection == null ) return null;
  Connection.Open();
  try
  {
    using ( var command = new SqlCommand($"select {nameColumn} from {nameTable}", Connection) )
    using ( var reader = command.ExecuteReader() )
    {
      var table = new DataTable();
      table.Columns.Add(nameColumn, typeof(string));
      table.Load(reader);
      return table;
    }
  }
  finally
  {
    Connection.Close();
  }
}

private void FillFromLookupTable(ComboBox combobox, DataTable table, string column)
{
  ...
}