Search code examples
c#backgroundworkerexternal-methods

Background worker not working


I have one form calling a method in another form. but the method in the other form does not work properly.
Form2 calls main:

private void button1_Click(object sender, EventArgs e)
{
    main ma = new main();
    ma.AddType(txtName.Text,txtURL.Text,12);
    this.Close();
}

main: (Adds one row to the xml and reloads the datagrid from xml)

public void AddType(string name, string url, int interval)
{

    string path = Application.StartupPath + @"\sites.xml";
    //create new instance of XmlDocument
    XmlDocument doc = new XmlDocument();
    //load from file
    doc.Load(path);
    //create node and add value
    XmlNode node = doc.CreateNode(XmlNodeType.Element, "site", null);
    node.InnerXml = "<Name>"+name+"</Name><URL>"+url+"</URL><Status></Status><Response-Time></Response-Time><Last-Checked></Last-Checked>";
    //add to elements collection
    doc.DocumentElement.AppendChild(node);
    //save back
    doc.Save(path);
    bwLoadXML.RunWorkerAsync();
}

The bwLoadXML.RunWorkerAsync(); does not show the new xml in the datagrid for some reason.

Edit, Here is the backgroundWorker:

/////////////////////////////////
        ////Populate Grid from XML
        /////////////////////////////////
        private void bwLoadXML_DoWork(object sender, DoWorkEventArgs e)
        {
            gridPopulate();
        }
        private void gridPopulate()
        {

            DataSet data = new DataSet(); string p = System.IO.Path.Combine(Application.StartupPath, "sites.xml");
            data.ReadXml(p);
            if (this.dataGrid.InvokeRequired)
            {
                this.dataGrid.Invoke(new MethodInvoker(delegate
                {
                    this.dataGrid.DataSource = data;
                    this.dataGrid.DataMember = "site";
                }));
            }
            else
            {
                this.dataGrid.DataSource = data;
                this.dataGrid.DataMember = "site";
            }
            int i = 0;
            foreach (DataGridViewColumn column in this.dataGrid.Columns)
            {
                if (i != 0)
                {
                    if (column.Name == "Name" || column.Name == "Status" || column.Name == "URL" || column.Name == "Response-Time" || column.Name == "Last-Checked")
                    {
                        //column.AutoSizeMode
                        column.Visible = true;
                        //column.Width = (int)(dataGrid.Width * .2) + (column.Name.Length / 2)-9;
                        /*if (column.Name == "URL")
                        {
                            ColumnHeader ch = new ColumnHeader();
                            //ch.
                        }*/
                    }
                    else
                    {
                        column.Visible = false;
                        //dataGrid.Columns[i+1].CellType = new DataGridViewButtonColumn();
                        //dataGrid.Columns[i+1].HeaderCell.
                    }
                }
                i++;
            }
            if (this.dataGrid.InvokeRequired)
            {
                this.dataGrid.Invoke(new MethodInvoker(delegate
                {
                    // If column 3 is the checkbox column, we sit it's resize mode to none:
                    dataGrid.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
                    // Then we set the width:
                    dataGrid.Columns[0].Width = 25;
                    dataGrid.Columns[0].DefaultCellStyle.Padding = System.Windows.Forms.Padding.Empty;
                    // If column 3 is the checkbox column, we sit it's resize mode to none:
                    dataGrid.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
                    // Finally we set the rest of the grid to fill or what ever resizing you need:
                    dataGrid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
                }));
            }
            else
            {
                // If column 3 is the checkbox column, we sit it's resize mode to none:
                dataGrid.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
                // Then we set the width:
                dataGrid.Columns[0].Width = 25;
                dataGrid.Columns[0].DefaultCellStyle.Padding = System.Windows.Forms.Padding.Empty;
                // If column 3 is the checkbox column, we sit it's resize mode to none:
                dataGrid.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
                // Finally we set the rest of the grid to fill or what ever resizing you need:
                dataGrid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            }
        }

Solution

  • Your problem is stemming from the fact that your button click method creates a new, separate Main form and does not interact with the one you expect. Since your new form is no longer referenced as soon as the button click is done, the background worker probably never gets a chance to start. You'll need to set up and hold a reference to the main form to work with it.

    public class Form2 : ... {
      main ma;
    
      public Form2(main ma) {
        this.ma = ma;
      }
    
      private void Button1_Click(object sender, EventArgs e) {
        this.ma.AddType(txtName.Text, txtUrl.Text, 12);
        this.Close();
      }
    }
    

    And from the main form, when you create the second form and show it you'll need to pass in the form it expects:

    void DoingSomething() {
      Form2 form = new Form2(this); // <-- this is where you pass in main
      form.ShowDialog();
    }