如何访问 TabPage 中动态添加的 DataGridView 并获取值?

How to access dynamically added DataGridView inside a TabPage and get values?

我制作了一个程序,可以导入 excel 文件并将所有工作表插入到动态添加的带有动态添加的数据网格视图的标签页中。

我想根据在组合框中选择的选项卡插入 KPI 列的值,每次更改选项卡页面时,组合框也会更改。

这是我的代码:

ReadExcel 方法

  public static void ReadExcel(ComboBox cboSheet, TabControl tabCon)
    {
       try
       {
           OpenFileDialog openFileDialog = new OpenFileDialog();
           openFileDialog.Filter = "Excel Files| *.xls; *xlsx";
           openFileDialog.ShowDialog();

           if (!string.IsNullOrEmpty(openFileDialog.FileName))
           {
               OleDbcon = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + openFileDialog.FileName + ";Extended Properties='Excel 12.0;HDR=Yes;IMEX=1;'");
               OleDbcon.Open();

               DataTable dt = OleDbcon.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
               OleDbcon.Close();

               cboSheet.Items.Clear();

               int width = 1330;
               int height = 565;
               //1338, 590

               for (int i = 0; i < dt.Rows.Count; i++)
               {
                    if (!dt.Rows[i]["Table_Name"].ToString().Contains("FilterDatabase") && !dt.Rows[i]["Table_Name"].ToString().EndsWith("$'"))
                    {
                       String sheetName = dt.Rows[i]["Table_Name"].ToString();
                       sheetName = sheetName.Substring(0, sheetName.Length - 1);
                        //cboSheet.Items.Add(sheetName);

                        TabPage tp = new TabPage(sheetName);

                        DataGridView dataGridView = new DataGridView();
                        tp.Controls.Add(dataGridView);
                        tabCon.Controls.Add(tp);
                        CreateDataGrid(dataGridView, sheetName);
                        dataGridView.Size = new Size(width, height);
                        System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle = new System.Windows.Forms.DataGridViewCellStyle();

                        //KPI Column
                    }
               }
           }
       }

       catch (Exception e)
       {
           MessageBox.Show(e.ToString());

       }

    }

CreateDataGrid 方法

  public static void CreateDataGrid(DataGridView dataGridView1, string TabName)
    {
        OleDbDataAdapter oleAdapt = new OleDbDataAdapter("Select * from [" + TabName + "$]", ExcelMethods.OleDbcon);


        DataTable dt = new DataTable();

        oleAdapt.Fill(dt);

        dataGridView1.DataSource = dt;
    }

下面是一个简单的 win 表单程序,它演示了我在评论中描述的内容。该表单包含一个名为 cb_KPI 的空 ComboBox。此外,它还包含一个名为 tabControl1.

的空 TabControl

已创建一个全局变量 AllDataTablesAlldataTables 是一个 DataSet,因此 DataSet 中的每个 DataTable 都是用户选择的 Excel 工作簿中的现有工作表。这用于保存每个 TabPageDataTable... 即 AllDataTables.Tables[0]tabControl1.TabPages[0]DataTable

加载表单时,AllDataTables 填充了用户选择的工作簿的工作表……然后,遍历所有 table 的循环将新的 TabPage 添加到 tabControl1 每个 table。最后,cb_KPI 组合框更新为包含当前所选 TabPage.

的值
DataSet AllDataTables;

public Form1() {
  InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e) {
  AllDataTables = GetDSFromExcel();
  foreach (DataTable dt in AllDataTables.Tables) {
    tabControl1.TabPages.Add(GetTabPageWithGrid(dt));
  }
  cb_KPI.DataSource = SetKPI_ValuesForComboBox(AllDataTables.Tables[tabControl1.SelectedIndex]);
}

GetDSFromExcel 方法 returns 来自用户选择的 Excel 文件的 DataSet,其中 DataSet 中的每个 DataTable 都是一个工作表来自用户选择的 Excel 文件。

private DataSet GetDSFromExcel() {
  DataSet ds = new DataSet();
  try {
    OpenFileDialog openFileDialog = new OpenFileDialog {
      Filter = "Excel Files| *.xls; *xlsx"
    };
    openFileDialog.ShowDialog();
    if (!string.IsNullOrEmpty(openFileDialog.FileName)) {
      using (OleDbConnection OleDbcon = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + openFileDialog.FileName + ";Extended Properties='Excel 12.0;HDR=Yes;IMEX=1;'")) {
        OleDbcon.Open();
        DataTable WorkbookSheetInfo = OleDbcon.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
        String sheetName;
        DataTable dt;
        OleDbDataAdapter oleAdapt;
        for (int i = 0; i < WorkbookSheetInfo.Rows.Count; i++) {
          if ((WorkbookSheetInfo.Rows[i]["Table_Name"].ToString().EndsWith("$'")) ||
              (WorkbookSheetInfo.Rows[i]["Table_Name"].ToString().EndsWith("$"))) {
            sheetName = WorkbookSheetInfo.Rows[i]["Table_Name"].ToString();
            dt = new DataTable(sheetName.Replace("'", "").Replace("$", ""));
            oleAdapt = new OleDbDataAdapter("Select * from [" + sheetName + "]", OleDbcon);
            oleAdapt.Fill(dt);
            ds.Tables.Add(dt);
          }
        }
      }
    }
  }
  catch (Exception e) {
    MessageBox.Show("ReadExcelIntoDS_Error" + e.ToString());
  }
  return ds;
}

GetTabPageWithGrid 方法被赋予一个 DataTable 和 returns 一个带有 DataGridView 的单个 TabPage 这样 DataGridView DataSource 将是给定的 DataTable

private TabPage GetTabPageWithGrid(DataTable dt) {
  TabPage tp = new TabPage(dt.TableName.Replace("'", "").Replace("$", ""));
  tp.Controls.Add(GetDGV(dt));
  return tp;
}

private DataGridView GetDGV(DataTable dt) {
  return new DataGridView {
    Size = new Size(1000, 400),
    Name = "datagridView" + dt.TableName,
    DataSource = dt,
    ScrollBars = ScrollBars.Both
  };
}

接下来是在用户选择不同的标签页时使 cb_KPI 组合框保持一致所需的代码。连接 TabControls SelectedIndexChanged 事件在这里可能会有帮助,代码只是循环遍历 DataTable 并收集所有不同的“KPI”字符串值并将它们存储到 List<string>然后 returns 完成的列表。这个新列表然后用作 cb_KPI 组合框的 DataSource。显然,如果 DataTable 很大或者有很多不同的 table,您可以考虑保存这些字符串列表,而不是每次用户选择不同的选项卡时都重新生成列表。注意:下面的代码假定 table 中有一列名为“KPI”。

private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) {
  cb_KPI.DataSource = SetKPI_ValuesForComboBox(AllDataTables.Tables[tabControl1.SelectedIndex]);
}

private List<string> SetKPI_ValuesForComboBox(DataTable dt) {
  List<string> kpiList = new List<string> {
    "All"
  };
  foreach (DataRow row in dt.Rows) {
    if (!kpiList.Contains(row["KPI"].ToString()))
      kpiList.Add(row["KPI"].ToString());
  }
  return kpiList;
}

希望对您有所帮助。