Venomz Venomz - 3 days ago 5
C# Question

listview not updating when method is called from another instance

When I call the Method

idload()
from another instance it does not update the list view list its supposed to. I know the method is getting called correctly because I placed a
MessageBox
after each statement in
idload()
and it shown. if
idload()
is called from
Form2.cs
[the form that it's in] it works fine but If I call it from
Form4.cs
it does not update the listview.

I used
MessageBox.Show(xmlReader.GetAttribute("id"));
and when
idload()
gets called from
Form2.cs
it loops through every id in the xml once and updates the list view as expected. when it gets called from
Form4.cs
it loops through everything twice and does not update the listview.

Here are the Relevant parts of code:

Form4.cs

public void myMethod()
{
Form2 form2 = new Form2();
form2.idload();
}

public void idwrite()
{
XElement xml = XElement.Load("settings.xml");
xml.Add(new XElement("Chat",
new XAttribute("id", textBox1.Text),
new XAttribute("name", textBox2.Text)));
xml.Save("settings.xml");
myMethod();
this.Close();
}


Form2.cs

public void idload()
{

listView1.Items.Clear();

XmlReader xmlReader = XmlReader.Create("settings.xml");

while (xmlReader.Read())
{

if ((xmlReader.NodeType == XmlNodeType.Element) && (xmlReader.Name == "Chat"))
{
if (xmlReader.HasAttributes)
{

// listView1.Items.Add(xmlReader.GetAttribute("id"));
// listView1.Items.Add(xmlReader.GetAttribute("name"));

string[] arr = new string[4];
ListViewItem itm;


arr[0] = (xmlReader.GetAttribute("id"));
arr[1] = (xmlReader.GetAttribute("name"));


itm = new ListViewItem(arr);
MessageBox.Show(xmlReader.GetAttribute("id"));
listView1.Items.Add(itm);

}
}
}

xmlReader.Close();

}


Here is the Project if needed: https://ufile.io/8dc20

Really confused why this is happening as there are no errors when debugging so any help is appreciated.

Thanks.

Answer

This is a common problem that is rooted in the OOP concept of instance. You have already an instance of Form2 displayed, but your code creates a NEW instance of Form2 and never shows it. Now the code calls the method using that new instance and works with the its ListView.
Of course, being the instance never shown, you don't see any change.
If you call form2.Show after the call to idload you will see your changes on the different instance.

The simplest workaround is to ask the Winforms engine to give you back a reference to the already shown instance of Form2 through the Application.OpenForms collection. Here you can select the reference to the Form2 instance with the extension OfType and getting the first form of that type available. If there is none then create and show it.

public void myMethod()
{
    Form2 form2 = Application.OpenForms.OfType<Form2>().FirstOrDefault();     
    if(form2 != null) 
        form2.idload();
    else
    {
        form2 = new Form2();
        form2.Show();
        form2.idload();
    }
}
Comments