如何访问 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
已创建一个全局变量 AllDataTables
。 AlldataTables
是一个 DataSet
,因此 DataSet
中的每个 DataTable
都是用户选择的 Excel 工作簿中的现有工作表。这用于保存每个 TabPage
的 DataTable
... 即 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;
}
希望对您有所帮助。
我制作了一个程序,可以导入 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
已创建一个全局变量 AllDataTables
。 AlldataTables
是一个 DataSet
,因此 DataSet
中的每个 DataTable
都是用户选择的 Excel 工作簿中的现有工作表。这用于保存每个 TabPage
的 DataTable
... 即 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;
}
希望对您有所帮助。