Click here to Skip to main content
15,867,686 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi.

I have 2 winforms in my project. Form1 and Form2.
And there's a list box named listBox1 in Form1 and a button named button2 in Form2.
I want to add a string to the listbox in the Form1 when user clicks the button2 in Form2.

And I tried to do that with that get set thing..
Here's my attempt.

////These lines are in the Form1 class
C#
private string itemToAdd;
public string itemToAddChanged
{
    get
    {
        return itemToAdd;
    }
    set
    {
        itemToAdd = value;
        listBox1.Items.Add(itemToAdd);
    }
}



////And these lines are in the Form2 button2 click event
C#
Form1 form = new Form1();
form.itemToAddChanged = "foo x 2";


So it doesn't add a thing to the listbox1.
And I tried to use public methods (both normal one and static one) to add items to the listBox1 and it fails too.

What is the correct way to do that ?

Thanks in advance !
Posted

1 solution

You are creating a new instance of Form1 every time the user clicks button2 in Form2; my guess is that you are never making that instance visible by calling 'Show on it.

If Form2 is your Main Form, and creates Form1, then create one instance of Form1: in the Load EventHandler for Form2, make it visible with 'Show, and then you'll find that your button2 Click EventHandler will do the right thing: Example 1:
C#
// in Form2's class-level code
Form1 InstanceOfForm1 = new Form1();

// in Form2's Load Event
private void Form2_Load(object sender, System.EventArgs e)
{
     InstanceOfForm1.Show();
}

// in Form2's button2 click event
private void button2_Click(object sender, EventArgs e)
{
     InstanceOfForm1.itemToAddChanged = "foo x 2";
}
However, if Form1 is your main Form, and Form1 creates Form2, a different strategy is called for: Example 2:
C#
// in Form1's class-level code
Form2 InstanceOfForm2 = new Form2();

// in Form1's Load Event
private void Form2_Load(object sender, System.EventArgs e)
{
     InstanceOfForm2.InstanceOfForm1 = this;
     InstanceOfForm2.Show();
}

// in Form2's class-level code:
public Form1 InstanceOfForm1;

// in Form2's button2 Click EventHandler
private void button2_Click(object sender, EventArgs e)
{
     InstanceOfForm1.itemToAddChanged = "foo x 2";
}
However, there are better ways to handle the case where Form1 is the Main Form, and creates Form2, such as: exposing only the ListBox on Form1 to Form2, or writing a custom Event that is fired in Form2 when button2 is clicked, and which is subscribed to by Form1.

Another alternative is to expose Button2 on Form2 to Form1; then Form1 can subscribe to the Click Event of button2: Example 3:
C#
// in Form1's class-level code
Form2 InstanceOfForm2 = new Form2();

// in Form1's Load Event
private void Form1_Load(object sender, System.EventArgs e)
{
     InstanceOfForm2.Form2Button2 .Click += Form2Button2_Click;
     InstanceOfForm2.Show();
}

private void Form2Button2_Click(object sender, EventArgs e)
{
    itemToAddChanged = "foo x 2";
}

// in Form2's class-level code:
public Button Form2Button2 { set; get; }

// in Form2's Load EventHandler
private void Form2_Load(object sender, EventArgs e)
{
    Form2Button2 = this.button2;
}
In the second example, the instance of Form1 was exposed to the instance of Form2; in the third example, only the ListBox on Form1 was exposed to Form2. And, the third example makes the assumption that Form2 does not need to "pass" to Form1 different text messages, which is, quite possibly, incorrect.

Hopefully, you'll get some ideas from these examples. There are even more ways to achieve inter-form communication (such as via the use of Interfaces, or the insertion of dynamic pointers Action, Func into Classes). imho, a good principle to follow is to try and expose to the "outside" of any given Form (or Object) only the minimum necessary for a given task; this increases the modularity of your code, and reduces potential for errors, and puzzling side-effects.

May I suggest that you will learn more if you write out, and test, yourself, an example where Form2 raises a custom Event which is subscribed to by Form1, and an example where Form1 exposes only the ListBox to Form2.
 
Share this answer
 
v2
Comments
johannesnestler 16-Sep-14 5:58am    
Very good answer Bill! - 5ed
BillWoodruff 16-Sep-14 6:31am    
Thank you Johannes !
M­­ar­­­­k 16-Sep-14 6:46am    
Form1 is the main form and Form2 is the secondary form.
With these methods, I have to close the opened Form1 and create a new instance of it instead of closed Form1 and show it as the Form2 loads. But with this method all the user inputs that were stored in textboxes will lose.
Storing them in somewhere else and assigning them back would ruin the performance of the program.
:(
BillWoodruff 17-Sep-14 1:04am    
"With these methods, I have to close the opened Form1 ..." Hi Mark, with the methods I show you above, the Forms are never closed and re-opened. Any Windows Form that is 'closed disposes of all it in-memory data, like contents of TextBoxes, etc.

And, of course, the Main Form, when closed in Win Forms has the default behavior that it always terminates the Application which closes all secondary Forms.

To re-use a Form without losing data: use the 'Hide operator, not 'Close; use the 'Show operator, or set the Form's 'Visible property back to 'true to display the Form again.

cheers, Bill

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900