DataGridView 没有 refresh/load 正确
DataGridView doesn't refresh/load properly
我正在编写一个使用 "Excel Sheets".
的程序
我正在通过按钮将它们加载到 DataGridView 中。如果我完成了 Sheet 的工作,我可以按相同的按钮加载另一个 Sheet。问题是即使我正在清除和刷新我的 DataGridView,旧的 Sheet 不会消失,新的 Sheet 只是添加到旧的下面。这是为什么?
我的按钮点击事件代码:
private void button1_Click(object sender, EventArgs e)
{
//Excell Prozess kill (wenn "Datei öffnen" geklickt)
Process[] excelProcs = Process.GetProcessesByName("EXCEL");
foreach (Process proc in excelProcs)
{
proc.Kill();
}
//Preparing Excel
Excel.Workbook theWorkbook = null;
Excel.Application ExcelObj = null;
Excel.Sheets sheets = null;
Excel.Worksheet worksheet = null;
if (dataGridView1.DataSource != null)
{
dataGridView1.DataSource = null;
dataGridView1.Refresh();
}
else
{
dataGridView1.Columns.Clear();
}
//Deklaration
string filePath = string.Empty;
string fileExt = string.Empty;
//File dialog
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "Excel Datei (*.xlsx *.xls)|*.xlsx; *.xls; |All Files (*.*)|*.*";
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
filePath = dialog.FileName; //get the path of the file
fileExt = Path.GetExtension(filePath); //get the extension from the file
//File Path zeigen
label1.Text = filePath;
//Nur .xls und .xlsx
if (fileExt.CompareTo(".xls") == 0 || fileExt.CompareTo(".xlsx") == 0)
{
try
{
ExcelObj = new Excel.Application();
//open ExcelObj and load it into theWorkbook
theWorkbook = ExcelObj.Workbooks.Open(filePath);
sheets = theWorkbook.Worksheets;
//Get the reference of second worksheet
worksheet = (Excel.Worksheet)sheets.get_Item(1);
//Get the name of worksheet
string strWorksheetName = worksheet.Name;
//string for database con
String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
filePath
+ ";Extended Properties='Excel 12.0 XML;HDR=NO;';";
OleDbConnection con = new OleDbConnection(constr);
//select sheet from excel file
OleDbCommand oconn = new OleDbCommand("Select * From [" + strWorksheetName + "$]", con);
//open db
con.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(oconn);
sda.Fill(data);
//insert data into datagridview
dataGridView1.DataSource = data;
//Select all from table date
DataRow[] rows = data.Select();
//close db
con.Close();
//close ExcelObj
ExcelObj.Quit();
}
//if error -> show
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
finally
{
//ComObject release
if (sheets != null) Marshal.ReleaseComObject(sheets);
if (ExcelObj != null) Marshal.ReleaseComObject(ExcelObj);
if (worksheet != null) Marshal.ReleaseComObject(worksheet);
if (theWorkbook != null) Marshal.ReleaseComObject(theWorkbook);
}
我认为问题是由 "Excel 文件" 未在 " 准备 Excel 中正确释放引起的“ 部分,但 ”Excel“ 在许多情况下通过“Excel Prozess Kill”代码。我通过任务管理器看了几次。那么是什么导致了这个问题?有什么意见吗?
您当前的代码中有一些令人头疼的事情,您可能需要重新考虑。
首先……杀死所有“Excel”进程很……奇怪。您的代码可能没有启动这些进程;但是代码会杀死他们。跟开始 运行 Excel 然后走开去喝咖啡的人见鬼去吧。
代码“似乎”正确地释放了 Excel 进程,但是,在您释放工作簿“之后”释放 Excel 应用程序似乎是合乎逻辑的。具体来说,先发布 sheets
,然后发布 worksheet
,然后发布 theWorkbook
,最后发布应用程序 ExcelObj
。因为代码“出现”以正确释放 Excel com 对象,所以我将转储所有杀死 Excel 进程的代码。
接下来,我建议在处理 Excel 文件时寻找第三方解决方案。对于非商业用途,我发现 EPPlus 是一个很好的替代品,而不是 OleDb
and/or Interop
并且可以在 NuGet 中找到。只是一个想法。
最后,我确实有一个简单的方法来解决您的问题。由于你没有显示它的定义,我可以破译的是变量 data
。在我看来,这个 data
对象是一个 DataTable
。在我的小测试中,正如你所描述的,当你 select 第二个 Excel 文件时,它确实会“附加”到现有的 data
DataTable
。由于代码“看起来”在填充之前永远不会清除 data
table,那么当您调用...
sda.Fill(data);
第二次,然后适配器会主动“附加”数据。
要解决此问题,只需在填充之前清除 data
table…
data = new DataTable();
sda.Fill(data);
我正在编写一个使用 "Excel Sheets".
的程序我正在通过按钮将它们加载到 DataGridView 中。如果我完成了 Sheet 的工作,我可以按相同的按钮加载另一个 Sheet。问题是即使我正在清除和刷新我的 DataGridView,旧的 Sheet 不会消失,新的 Sheet 只是添加到旧的下面。这是为什么?
我的按钮点击事件代码:
private void button1_Click(object sender, EventArgs e)
{
//Excell Prozess kill (wenn "Datei öffnen" geklickt)
Process[] excelProcs = Process.GetProcessesByName("EXCEL");
foreach (Process proc in excelProcs)
{
proc.Kill();
}
//Preparing Excel
Excel.Workbook theWorkbook = null;
Excel.Application ExcelObj = null;
Excel.Sheets sheets = null;
Excel.Worksheet worksheet = null;
if (dataGridView1.DataSource != null)
{
dataGridView1.DataSource = null;
dataGridView1.Refresh();
}
else
{
dataGridView1.Columns.Clear();
}
//Deklaration
string filePath = string.Empty;
string fileExt = string.Empty;
//File dialog
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "Excel Datei (*.xlsx *.xls)|*.xlsx; *.xls; |All Files (*.*)|*.*";
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
filePath = dialog.FileName; //get the path of the file
fileExt = Path.GetExtension(filePath); //get the extension from the file
//File Path zeigen
label1.Text = filePath;
//Nur .xls und .xlsx
if (fileExt.CompareTo(".xls") == 0 || fileExt.CompareTo(".xlsx") == 0)
{
try
{
ExcelObj = new Excel.Application();
//open ExcelObj and load it into theWorkbook
theWorkbook = ExcelObj.Workbooks.Open(filePath);
sheets = theWorkbook.Worksheets;
//Get the reference of second worksheet
worksheet = (Excel.Worksheet)sheets.get_Item(1);
//Get the name of worksheet
string strWorksheetName = worksheet.Name;
//string for database con
String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
filePath
+ ";Extended Properties='Excel 12.0 XML;HDR=NO;';";
OleDbConnection con = new OleDbConnection(constr);
//select sheet from excel file
OleDbCommand oconn = new OleDbCommand("Select * From [" + strWorksheetName + "$]", con);
//open db
con.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(oconn);
sda.Fill(data);
//insert data into datagridview
dataGridView1.DataSource = data;
//Select all from table date
DataRow[] rows = data.Select();
//close db
con.Close();
//close ExcelObj
ExcelObj.Quit();
}
//if error -> show
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
finally
{
//ComObject release
if (sheets != null) Marshal.ReleaseComObject(sheets);
if (ExcelObj != null) Marshal.ReleaseComObject(ExcelObj);
if (worksheet != null) Marshal.ReleaseComObject(worksheet);
if (theWorkbook != null) Marshal.ReleaseComObject(theWorkbook);
}
我认为问题是由 "Excel 文件" 未在 " 准备 Excel 中正确释放引起的“ 部分,但 ”Excel“ 在许多情况下通过“Excel Prozess Kill”代码。我通过任务管理器看了几次。那么是什么导致了这个问题?有什么意见吗?
您当前的代码中有一些令人头疼的事情,您可能需要重新考虑。
首先……杀死所有“Excel”进程很……奇怪。您的代码可能没有启动这些进程;但是代码会杀死他们。跟开始 运行 Excel 然后走开去喝咖啡的人见鬼去吧。
代码“似乎”正确地释放了 Excel 进程,但是,在您释放工作簿“之后”释放 Excel 应用程序似乎是合乎逻辑的。具体来说,先发布 sheets
,然后发布 worksheet
,然后发布 theWorkbook
,最后发布应用程序 ExcelObj
。因为代码“出现”以正确释放 Excel com 对象,所以我将转储所有杀死 Excel 进程的代码。
接下来,我建议在处理 Excel 文件时寻找第三方解决方案。对于非商业用途,我发现 EPPlus 是一个很好的替代品,而不是 OleDb
and/or Interop
并且可以在 NuGet 中找到。只是一个想法。
最后,我确实有一个简单的方法来解决您的问题。由于你没有显示它的定义,我可以破译的是变量 data
。在我看来,这个 data
对象是一个 DataTable
。在我的小测试中,正如你所描述的,当你 select 第二个 Excel 文件时,它确实会“附加”到现有的 data
DataTable
。由于代码“看起来”在填充之前永远不会清除 data
table,那么当您调用...
sda.Fill(data);
第二次,然后适配器会主动“附加”数据。
要解决此问题,只需在填充之前清除 data
table…
data = new DataTable();
sda.Fill(data);