I have a Report Generator Form that has two dates
From and To:
When entered from and to dates and button click to generate report it goes into:
private void generateReport_Click
below: is an instance of my datagridview
TR = Application.OpenForms.OfType().ElementAt(0);
I'm taking all the data from my datagridview and converting into data-table.
then XML writes this datatable into transactionreport.xml file,
this file then loads up into crystal report to display report.
I then dispose of my report.
Basically I want to show user, how much time it is taking to generate a report by creating background worker and reporting progress with progress bar, however this is giving me cross-thread exception.
public partial class TransactionRptGenForm : Form
{
Records TR = new Records();
public TransactionRptGenForm()
{
InitializeComponent();
}
public DataSet2 ds;
public System.Data.DataTable dt;
private void generateReport_Click(object sender, EventArgs e)
{
// Start the BackgroundWorker.
backgroundWorker1.RunWorkerAsync();
}
private void TransactionRptGenForm_Load(object sender, EventArgs e)
{
this.MaximizeBox = false;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
backgroundWorker1.ReportProgress(5);
TR = Application.OpenForms.OfType<Records>().ElementAt(0);
// Report Form.
TReportDisplay TRD = new TReportDisplay();
Treport treport1 = new Treport();
backgroundWorker1.ReportProgress(10);
try
{
ds = new DataSet2();
dt = new System.Data.DataTable();
dt = ConvertDGVtoDataTable(TR.transcationTableDataGridView);
ds.Tables.Add(dt);
backgroundWorker1.ReportProgress(20);
try
{
ds.WriteXmlSchema("TransactionReport.xml");
treport1.SetDataSource(ds);
TRD.crystalReportViewer2.ReportSource = treport1;
backgroundWorker1.ReportProgress(40);
ParameterFieldDefinitions Parameters;
ParameterFieldDefinition Parameter;
ParameterValues Values = new ParameterValues();
ParameterDiscreteValue DiscreteValue = new ParameterDiscreteValue();
backgroundWorker1.ReportProgress(60);
DiscreteValue.Value = dateTimePicker1.Text;
Parameters = treport1.DataDefinition.ParameterFields;
Parameter = Parameters["fromdate"];
Values = Parameter.CurrentValues;
Values.Clear();
Values.Add(DiscreteValue);
Parameter.ApplyCurrentValues(Values);
backgroundWorker1.ReportProgress(70);
DiscreteValue.Value = dateTimePicker2.Text;
Parameters = treport1.DataDefinition.ParameterFields;
Parameter = Parameters["todate"];
Values = Parameter.CurrentValues;
backgroundWorker1.ReportProgress(80);
Values.Add(DiscreteValue);
Parameter.ApplyCurrentValues(Values);
backgroundWorker1.ReportProgress(100);
TRD.ShowDialog();
TR.Dispose();
}
catch (CrystalReportsException)
{
{ MessageBox.Show("Please install crystal reports runtime to view reports.", "Crystal Reports Missing"); }
}
catch (Exception ex) { MessageBox.Show(ex.Message.ToString()); };
}
catch (Exception ex) { MessageBox.Show(ex.Message.ToString()); }
}
// This is the method that converts DataGridView into DataTable.
public static System.Data.DataTable ConvertDGVtoDataTable(DataGridView DGV)
{
System.Data.DataTable dt = new System.Data.DataTable();
dt.Columns.Add("ID", typeof(Int16));
dt.Columns.Add("Transaction Type", typeof(string));
dt.Columns.Add("Transaction Details", typeof(string));
foreach (DataGridViewRow dgv in DGV.Rows)
{
dt.Rows.Add(dgv.Cells[0].Value, dgv.Cells[1].Value, dgv.Cells[2].Value);
}
return dt;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
}
}
please explain what does this.invoker method do, what are thread unsafe calls and safe calls.