0

I have a button which when pressed closes the current form and opens a new form of the same class - i.e. so it opens a new form in it original state.

I have another button which has the same functionality, however I try to call a function in the code so when the new form opens it runs importGantt() a function of the form.

The problem I have is that when I click the button it closes the current form and opens a new one, as expected, however it does not call the importGantt() function until I close the application.

Any ideas?

Much appreciated.

private void browseFileToolStripMenuItem_Click(object sender, EventArgs e)
    {
        clearAndImport();
    }

private void clearAndImport()
    {
        this.Hide();
        Dashboard dashboard = new Dashboard();
        dashboard.ShowDialog();
        dashboard.importGantt();
        this.Close();
    }

private void importGantt()
    {
        // Edit Interface
        btnImport.Visible = false;
        dataCapPlan.Visible = true;
        dataMilestones.Visible = true;
        pnlGantt.Visible = true;
        Graphics ganttGraphics = pnlGantt.CreateGraphics();

        // Draw axis


        // Import Files
        fileCapPlan.Title = "Select Capital Plan File";
        fileCapPlan.Filter = "Excel Workbook (.xlsx)|*.xlsx";
        DialogResult resCapPlan = fileCapPlan.ShowDialog();
        if (resCapPlan == DialogResult.OK)
        {
            cnStr = cnStr + fileCapPlan.FileName;
        }
        else
        {
            MessageBox.Show("Error: Unable to import file");
        }
        fileMilestones.Title = "Select Milestones File";
        fileMilestones.Filter = "Excel Workbook (.xlsx)|*.xlsx";
        DialogResult resMilestones = fileMilestones.ShowDialog();
        if (resMilestones == DialogResult.OK)
        {
            cnStr2 = cnStr2 + fileMilestones.FileName;
        }
        else
        {
            MessageBox.Show("Error: Unable to import file");
        }

        // Use OleDb connection to import Excel data
        using (OleDbConnection cn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + cnStr + ";Extended Properties=" + "'EXCEL 12.0 Xml;HDR=YES'"))
        {
            using (OleDbDataAdapter adapter = new OleDbDataAdapter(sqlSelectAll, cn))
            {
                adapter.Fill(dtCapPlan);
                dataCapPlan.DataSource = dtCapPlan;
                dataCapPlan.AutoResizeColumns();
            }
        }
        using (OleDbConnection cn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + cnStr2 + ";Extended Properties=" + "'EXCEL 12.0 Xml;HDR=YES'"))
        {
            using (OleDbDataAdapter adapter = new OleDbDataAdapter(sqlSelectAll, cn))
            {
                adapter.Fill(dtMilestones);
                dataMilestones.DataSource = dtMilestones;
                dataMilestones.AutoResizeColumns();
            }
        }

        // Draw Gantt Chart
        foreach (DataRow rowCapPlan in dtCapPlan.Rows)
        {
            id = rowCapPlan["Program ID"].ToString();

            foreach (DataRow rowMilestone in dtMilestones.Rows)
            {
                if (id == rowMilestone["Program ID"].ToString())
                {
                    // calculate space in days from todays date and the milestone date
                    msDate = Convert.ToDateTime(rowMilestone["Milestone Date"]);
                    msTimespan = msDate - calDate;
                    msIntDate = (int)msTimespan.TotalDays + 1;
                    tTimespan = tDate - calDate;
                    tIntDate = (int)tTimespan.TotalDays + 1;
                    ganttPlotSpace = msIntDate - tIntDate;

                    // Draw each milestone or gateway which is not yet complete
                    if (rowMilestone["% Complete"].ToString() != "100")
                    {
                        taskname = rowMilestone["Task Name"].ToString();
                        if (taskname == "Gateway 1" || taskname == "Gateway 2" || taskname == "Gateway 3" || taskname == "Gateway 4" || taskname == "Gateway 5")
                        {
                            Rectangle gw = new Rectangle(startx + ganttPlotSpace, starty - 4, 2, 11);
                            ganttGraphics.DrawRectangle(gwPen, gw);
                            ganttGraphics.FillRectangle(gwBrush, gw);
                        }
                        else
                        {
                            Rectangle ms = new Rectangle(startx + ganttPlotSpace + 1, starty, 2, 2);
                            ganttGraphics.DrawRectangle(msPen, ms);
                            ganttGraphics.FillRectangle(msBrush, ms);
                        }
                        ganttGraphics.DrawLine(linePen, startx - 10, starty - 11, pnlGantt.Right, starty - 11);
                    }
                }
            }
            starty = starty + 22;
        }
        ganttGraphics.DrawLine(linePen, startx - 10, starty + 11, pnlGantt.Right, starty + 11);
    }

image with gantt enter image description here

image after clearAndImport method (FIXED by user) enter image description here


As per Brij guidance:

Okay, so with the guidance this almost works, the code is now as follows...

This now opens the new form and runs the import method, however, it seems to be running it on a loop. I.e. it runs successfully displaying the gantt, but then tries to run the import gantt method again.

bool clear;



public Dashboard(bool clear = false)
    {
        InitializeComponent();
        dataCapPlan.ColumnHeaderMouseClick += new DataGridViewCellMouseEventHandler(dataCapPlan_ColumnHeaderMouseClick);

        this.clear = clear;
        this.Load += new EventHandler(Dashboard_Load);
    }
    private void Dashboard_Load(object sender, EventArgs e)
    {
        if (this.clear)
        {
            this.importGantt();
        }
    }

// Clear and import method
    private void clearAndImport()
    {
        this.Hide();
        Dashboard dashboard = new Dashboard();
        dashboard.clear = true;
        dashboard.ShowDialog();
        this.Close();
    }
NickB6
  • 209
  • 2
  • 5
  • 16
  • 1
    Why close and reopen the same form? Why don't you just update it? – Nolonar Apr 05 '13 at 11:40
  • Hi @Nolonar, thanks for response. I originally tried that. But I came across so many errors; clearing the datatables, the panel and then trying to re-import the excel data using the oledb. Part of the functionality is to clear the form back to original state anyway, so want to use it this way. Also the forms interface changes when the function is run, so is easiest way just to restore back to normal (I assume!). – NickB6 Apr 05 '13 at 11:44

2 Answers2

1

I think the method that you are referring is below:

private void clearAndImport()
{
        this.Hide();
        Dashboard dashboard = new Dashboard();
        dashboard.ShowDialog();
        dashboard.importGantt();
        this.Close();
}

You are calling dashboard.ShowDialog(). So until you close the "Dashboard" form, next line of code (dashboard.importGantt()) won't get called. I suggest you call importGantt() in constructor or Load event of Dashboard form. You could change the sequence of code as well by moving dashboard.importGantt() above dashboard.ShowDialog().


As per your comment, I suggest, modify the constructor of Dashboard class to accept a boolean parameter and make it optional (defaulting to false). If true is passed, then only call importGantt(). So it will be like:

public Dashboard(bool clear = false)
{
   InitializeComponent();
   if(clear)
   {
       this.importGantt();
   }
}

and the you clearAndImport() method will be like:

private void clearAndImport()
{
        this.Hide();
        Dashboard dashboard = new Dashboard(true);
        dashboard.ShowDialog();
        this.Close();
}

As per my last comment, try this:

bool clear = false;
public Dashboard(bool clear = false)
{
        InitializeComponent();
        this.clear = clear;
        this.Load += new EventHandler(Dashboard_Load);
}

void Dashboard_Load(object sender, EventArgs)
{
    if(this.clear)
    {
       this.importGantt();
    }
}
Brij
  • 11,731
  • 22
  • 78
  • 116
  • Thanks for the response, makes absolute sense! The only problem I have is that I don't want the call the function when the application form opens, only in the instance where the user wants to clear the dashboard and re-import. At the moment the user can clear the dashboard (closes and opens new form), then in the new form use the import button as separate entities, but I want to combine these into one function. – NickB6 Apr 05 '13 at 11:51
  • See further additions to the answer above. – Brij Apr 05 '13 at 12:06
  • Brilliant, thank you ever so much. This partly works... it for some reason doesn't complete the panel graphics drawing part of the method. I'll add a pic in the question of what the method does if I call it individually and another for the clear and import method. – NickB6 Apr 05 '13 at 12:17
  • Try this: save the value of "clear" parameter in a local variable of `Dashboard` class and move the `if(clear) { this.importGantt(); }` code to `Load` event of the `DashBoard` class. – Brij Apr 05 '13 at 12:48
  • Hi, thanks again. not sure i have done this right. ` public Dashboard() { InitializeComponent(); dataCapPlan.ColumnHeaderMouseClick += new DataGridViewCellMouseEventHandler(dataCapPlan_ColumnHeaderMouseClick); if (clear) { this.importGantt(); } }` – NickB6 Apr 05 '13 at 13:23
  • private void clearAndImport() { this.Hide(); Dashboard dashboard = new Dashboard(); dashboard.ShowDialog(); dashboard.clear = true; this.Close(); } – NickB6 Apr 05 '13 at 13:24
  • see my suggestions at the end – Brij Apr 05 '13 at 17:26
  • Thank you, this is really helpful, almost there I think. See my added info for Brij in the original posted question.... Any ideas what might be causing the loop? – NickB6 Apr 06 '13 at 08:38
  • Ps. I have tried adding code `clear = false;` which stops it from looping, but it seems to undo or clear all the graphics drawn in the importGantt method... – NickB6 Apr 06 '13 at 08:48
0

Try dashboard.Show(); instead of dashboard.ShowDialog();

using (var dashboard = new Dashboard())
{
    dashboard.Show(); // Show the form
    dashboard.importGantt(); // Call
    dashboard.Close(); // Close it when you're done...
} 
eMi
  • 5,540
  • 10
  • 60
  • 109
  • Thanks for the response, this works, however now the application closes after the new form has called the function. – NickB6 Apr 05 '13 at 11:52
  • U could provide a timer within your Form to have it close, or pass a delegate into the Form to run your method on Show, after which it could close itself. – eMi Apr 05 '13 at 11:58
  • @NickB6 - You are running into issues because of the way you want to do it. The correct way would be to Invoke the changes to the controls on the form if thats required. Your code is flawed and actually working as its programmed. – Security Hound Apr 05 '13 at 12:29
  • Hi @Ramhound, thanks for response. Yes I do understand this, as per comment to q on my OP, i tried refreshing as such all the form controls, however ran into lots of errors. Any advice on how, see pics in OP, to refresh the two datatables (viewed in datagridview) and the panel of graphics? Do i need to delete/invalidate them and create new instances? I tried using the controls clear methods, however this did not work. – NickB6 Apr 05 '13 at 12:36