I have a code that it's purpose is to export a grid to excel.
The Grid is created in runtime (without a form) and so does the ulraGridExcelExporter...
If I create the grid on a different Thread other than the main GUI thread, export it to a file and then double click on the created file in order to open it, then my computer will lock.
I mean, I cannot do "Go to Desktop" or open "My Copmuter" and the disktop itself is not repoponding.
The Excel file will also not open...
The system will be released only after I close the application that tried to export to excel.
Here is small code that shows the problem:
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using Infragistics.Win.UltraWinGrid;using Infragistics.Win.UltraWinGrid.ExcelExport;
namespace ExcelExportProblem{ public partial class Form1 : Form { UltraGrid grid; string filePath = ""; public Form1() { InitializeComponent(); }
private void button1_Click(object sender, EventArgs e) { SaveFileDialog ofd = new SaveFileDialog() { FileName = "", Title = "Select Destination Excel File", Filter = "Microsoft Excel File (*.xls)|*.xls", InitialDirectory = System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), };
if (ofd.ShowDialog() != DialogResult.OK) { filePath = ""; return; }
filePath = ofd.FileName;
MethodInvoker mi = delegate() { grid = new UltraGrid(); grid.BindingContext = new BindingContext();
DataTable dt = new DataTable(); dt.Columns.Add("Col1"); dt.Columns.Add("Col2"); dt.Columns.Add("Col3");
for (int i = 0; i < 10; i++) { dt.Rows.Add(new object[] { 1, 2, 3 }); }
grid.SuspendLayout(); grid.SetDataBinding(dt, "");
foreach (var col in grid.DisplayLayout.Bands[0].Columns) { col.AutoSizeMode = Infragistics.Win.UltraWinGrid.ColumnAutoSizeMode.AllRowsInBand; col.Width = col.CalculateAutoResizeWidth(Infragistics.Win.UltraWinGrid.PerformAutoSizeType.AllRowsInBand, true); col.CellClickAction = Infragistics.Win.UltraWinGrid.CellClickAction.CellSelect; }
grid.ResumeLayout(true); };
mi.BeginInvoke(null, null); }
private void button2_Click(object sender, EventArgs e) { SaveFileDialog ofd = new SaveFileDialog() { FileName = "", Title = "Select Destination Excel File", Filter = "Microsoft Excel File (*.xls)|*.xls", InitialDirectory = System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), };
grid = new UltraGrid(); grid.BindingContext = new BindingContext();
grid.ResumeLayout(true); }
private void button3_Click(object sender, EventArgs e) { UltraGridExcelExporter ultraGridExcelExporter1 = new UltraGridExcelExporter(); ultraGridExcelExporter1.Export(grid, filePath); ultraGridExcelExporter1.Dispose(); } }}
Am I doing something wrong?
Is it a bug?
Is there a better way to do this? (I tried using InvokeRequired and grid.Invoke whenever I accessed the grid on the code of Button1, but it didn't help).
Thanks.
Hi,
I'm not sure why the file is locking up your machine, but there are quite a number of issues with that you are doing here.
For one thing, the grid variable is on the UI thread, and you are using this variable inside the second thread. So this is already a really bad idea.
For another, you are never adding the grid to the Controls collection of the form. So the grid never gets disposed.
Another, even worse issue, is that the ExcelExporter is created on the UI thread and it's using the grid which was created on the second thread.
Also, you are creating the grid on the second thread and once the thread finishes executing, it will simply go away. You are not doing anything to keep it alive, so the grid will be gone.
And, there's nothing to stop you from pushing Button1 and then pushing Button3 before the first thread has completed. Or pushing Button1 twice in rapid succession.
This is only an example!
On the real situation there are no buttons!. It is created that way that the export to excel will only be done after the grid was created and filled.
I've changed the code so the grid will be created on the UI thread, instead of the background worker and it does help with the locks.
However, I didn't write the original code. The original code is a huge and complex code that used to create DataGridView and use a method of Copy and Paste into Excel.
It was not using data binding, it was slow and it had some bugs.
I simply replaced some parts of the code so it will work with Infragistics grid and do some data binding.
The problem is that sometime the code I've edited is being called from a different thread, so I can't totally solve that problem.
I'm calling m_Grid.Dispose when I'm done with it.
I see no point of creating a form and adding the grid to a form if I don't need it. (The grid is just a method of exporting data to Excel).
Ok, so let me ask you a question....
Assuming I want to export a big grid that contain 256 columns and 65536 rows.
Using UltraGridExcelExporter in the main GUI might take like 30 seconds, or at least several seconds.
This will lock the GUI. How would someone can export it to excel without locking the GUI?