Question Access Form2 from Form1

Gr8Gpa

New member
Joined
Mar 27, 2021
Messages
3
Programming Experience
3-5
I have written a small Windows desktop app in C# that has two forms. Form1 contains activities that store and update statistics on a set of charts on Form2. When I open Form2 from a button on Form1 using ShowDialog(), I can see that the charts have been updated as expected. However, once Form2 has been opened and closed, new statistics are no longer updated from Form1 activities onto the Form2 charts. There is no exception thrown, and collected info on the charts is not deleted. New data just doesn't register anymore. Without going into a lot of details, has anyone heard of this behavior before? A breakpoint on Form1 shows that data is still being collected as before, and the code to send that data is being executed. The new data just doesn't show up. Also, this app works in VB.net where I first wrote it. Maybe I'm having trouble with my C# translation because of some difference in the two languages that I haven't learned yet.
 
Solution
Without seeing your code it is a bit hard to tell, but the most common reasons are two rookie mistakes:

- The second form instantiates another copy of the first form, and thinks it is talking to the original first form when in reality it is talking to a new instance.

- Using Windows forms controls UI (aka the View) for storing data (aka the Model), instead of creating one instance of the Model, and passing that around between the Views.
Without seeing your code it is a bit hard to tell, but the most common reasons are two rookie mistakes:

- The second form instantiates another copy of the first form, and thinks it is talking to the original first form when in reality it is talking to a new instance.

- Using Windows forms controls UI (aka the View) for storing data (aka the Model), instead of creating one instance of the Model, and passing that around between the Views.
 
Solution
Thank-you, Skydiver, for your speedy reply. It turned out to be an instantiation problem related to your first explanation. When I opened Form2 to look at the stats, and then closed it again, I was blocking it from being able to receive additional data. The solution was to reload Form2 immediately after ShowDialog() on Form1.
public void Button1_Click(object sender, EventArgs e)
{
MyForm2.ShowDialog();
MyForm2.Form2_Load(sender, e);
}
 
Thank-you, Skydiver, for your speedy reply. It turned out to be an instantiation problem related to your first explanation. When I opened Form2 to look at the stats, and then closed it again, I was blocking it from being able to receive additional data. The solution was to reload Form2 immediately after ShowDialog() on Form1.
public void Button1_Click(object sender, EventArgs e)
{
MyForm2.ShowDialog();
MyForm2.Form2_Load(sender, e);
}
No, no and double no! That is not a solution to anything. That is diabolical code. There are two ways to use a dialogue form. More often than not, you should be creating and destroying the form where and when you need it, e.g.
C#:
using (var dialogue = new SomeForm())
{
    // Push data into the dialogue form here, e.g.
    dialogue.SomeProperty = someValue;
    
    if (dialogue.ShowDialog() == DialogResult.OK)
    {
        // Pull data out of the dialogue here, e.g.
        var someOtherValue = dialogue.SomeOtherProperty;
        
        // ...
    }
}
You create the form object, push required data in, display it and then, if the user doesn't cancel the operation, get the data out when it closes and then destroy it. That is how you should use dialogues 99 times out of 100. There will be rare occasions where you need to use the same form object each time you display the dialogue. In that case, create a new instance the first time only and then keep displaying it each subsequent time, e.g.
C#:
private SomeForm dialogue;
and:
C#:
if (dialogue == null)
{
    dialogue = new SomeForm();
    
    // Push data required on the first run into the dialogue form here, e.g.
    dialogue.SomeProperty = someValue;
}
else
{
    // Push data required on subsequent runs into the dialogue form here, e.g.
    dialogue.SomeOtherProperty = someOtherValue;
}

// Push data required on every run into the dialogue form here, e.g.
dialogue.YetAnotherProperty = yetAnotherValue;

if (dialogue.ShowDialog() == DialogResult.OK)
{
    // Pull data out of the dialogue here, e.g.
    var theFinalValue = dialogue.TheFinalProperty;

    // ...
}
You create the form object on the first run only and then keep displaying the same form object, never destroying it.

If you're not doing one of those two things then you're doing it wrong.
 
Thanks for your reply, jmcilhinney. I see what you are saying. Also, I ran across your blog Managing Data Among Multiple Forms. Very informative, and pertinent to my self-training in C# at this point. I'll try to make my way through all this and report back. This may take a while.
 
Back
Top Bottom