I have two forms. First, Form1 has a group box, some labels and a listbox. I press a button and new Form2 is opened and contains some text. I want to transfer the text in Form2 to the listbox in the Form1.
So far, what I have done is make modifier of listbox to public and then put this code in the button of Form2
Form1 frm = new Form1();
frm.ListBox.items.Add(textBox.Text);
But amazingly, this does not add any value. I thought I was mistaken with the insertion so I made the same procedure. This time, I made a label public and added textbox value to its Text property but it failed.
Any ideas?
Try adding a parameter to the constructor of the second form (in your example, Form1) and passing the value that way. Once InitializeComponent() is called you can then add the parameter to the listbox as a choice.
public Form1(String customItem)
{
InitializeComponent();
this.myListBox.Items.Add(customItem);
}
// In the original form's code:
Form1 frm = new Form1(this.textBox.Text);
Let's assume Form1 calls Form2. Please look at the code:
Form1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.Show();
frm.VisibleChanged += formVisibleChanged;
}
private void formVisibleChanged(object sender, EventArgs e)
{
Form2 frm = (Form2)sender;
if (!frm.Visible)
{
this.listBox1.Items.Add(frm.ReturnText);
frm.Dispose();
}
}
}
Form2:
public partial class Form2 : Form
{
public string ReturnText { get; set; }
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.ReturnText = this.textBox1.Text;
this.Visible = false;
}
}
The answer is to declare public property on Form2 and when form gets hidden. Access the same instance and retrieve the value.
Below code working perfect on my machine.
private void button1_Click(object sender, EventArgs e)
{
Form1 f1 = new Form1();
f1.listBox1.Items.Add(textBox1.Text );//ListBox1 : Modifier property made public
f1.ShowDialog();
}
Ok, If you are Calling Sequence is like, Form1->Form2 and Form2 updates the value of Form1 then you have to use ParentForm() or Delegate to update the previous form.
Form1 frm = new Form1();
frm is now a new instance of class Form1.
frm does not refer to the original instance of Form1 that was displayed to the user.
One solution is, when creating the instance of Form2, pass it a reference to your current instance of Form1.
Please avoid the concept of making any public members like you said
>>i have done is make modifier of listbox to public and then in form2 in button code<<
this is not a good practice,on the other hand the good one is in Brad Christie's Post,I hope you got it.
This code will be inside the form containing myListBox probably inside a button click handler.
Form2 frm2 = new Form2();
frm2.ShowDialog();
this.myListBox.Items.Add(frm2.myTextBox.Text);
frm2.Dispose();
Related
I designed a form for login that named as form1, and have 2 more form form2,form3
form2 items showing in panel from form1
and what I want to do
when I click the button in panel ( the item from form2 ) want to show form2 and hide form1 but the code isnt working
private void button1_Click(object sender, EventArgs e)
{
Form1 frm1 = new Form1();
Form3 frm3 = new Form3();
frm1.Hide();
frm3.Show();
};
form3 is opening but form1 isnt hiding
Its not hiding because you created a new instance for form1 which is already instantiated.
You must call the Hide() method on the same instance used to call the Show() method.
If you added this code inside form1 class ,then change it like this
private Form1 frm1
public Form2()
{
frm1 = new Form1()
}
private void button_show_form1_Click(object sender, EventArgs e)
{
frm1.Show();
};
private void button1_Click(object sender, EventArgs e)
{
Form3 frm3 = new Form3();
frm3.Show();
frm1.Hide();
};
You creating both forms in your codesnipped. Form1 is not the form you want to close, i think. frm1 is only another instance of Form1, but not the openend instance von Form1. You must have anywhere another instance of Form1. You must use the right referenz to the right instance.
It is important to know that WinForms create an instance of the startup form. In our case the startup form would be Form1. So, when you say
Form1 frm1 = new Form1();
You're actually creating a new (second) instance of Form1. This means that, in code, there are two different Form1's.
What we want to do is check with our application to get the instance of Form1 that already exists.
// This goes in Form2. It returns an instance of Form1, if it exists.
private Form getForm1()
{
// Application holds information about our application, such as which forms are currently open.
var formCollection = System.Windows.Forms.Application.OpenForms;
// Now we loop through the open forms in search of the form we want, Form1.
foreach (Form frm in formCollection)
{
if (frm.Name.Equals("Form1"))
{
return frm;
}
}
return null;
}
Now that we can get the existing instance of Form1 we can use it to make the form hidden.
private void button1_Click(object sender, EventArgs e)
{
var form1 = getForm1();
if (form1 != null) form1.Hide();
}
Something to know here is that when a form is hidden it is not closed. So, we need to make sure that Form1 becomes visible again. For example, we can set Form1 to be visible when Form2 closes.
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
// The question mark (?) checks to see if the result of
// getForm1() is null. Same thing that is happening in
// button1_click
getForm1()?.Show();
}
Complete Form2 Code
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var frm1 = getForm1();
var frm3 = new Form3();
if (frm1 != null) frm1.Hide();
frm3.Show();
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
// The question mark (?) checks to see if the result of getForm1() is null. Same thing that is happening in button1_click
getForm1()?.Show();
}
// This goes in Form2. It returns an instance of Form1, if it exists.
private Form getForm1()
{
// Application holds information about our application, such as which forms are currently open.
// Note that Open and Visible have different definitions.
var formCollection = System.Windows.Forms.Application.OpenForms;
// Now we loop through the open forms in search of the form we want, Form1.
foreach (Form frm in formCollection)
{
if (frm.Name.Equals("Form1"))
{
return frm;
}
}
return null;
}
}
I try to update Form1 values from Form2, but nothing happens. No errors also, strange...
Form1:
public static Form2 f2{ get; set; } = new Form2();
private void addButton1_Click(object sender, EventArgs e)
{
f2.Show();
}
Form2:
public void button1_Click(object sender, EventArgs e)
{
Form f1 = new Form();
f1.label2.ForeColor = Color.Red;
}
Nothing happens. I can get data to my form2 from form1, but I cannot send, I mean I can, but nothing happens... Why? Thank you
The other solutions mentioned here would work for your specific case, but I encourage you to look at the big picture, and design a generalized solution that will work for most cases.
Your problem essentially boils down to doing something on one form based on the events of another form.
The best approach to do this is, in my opinion:
Let Form1 do all its own actions.
Let Form2 do all its own actions.
If you need to do something on Form1 based on an event that occurred on Form2, let Form2 notify Form1 that something happened there, so go do your own thing.
If necessary, pass data from Form2 to Form1.
So I would make use of delegates for this purpose.
Imagine you have a Button and a Label on your Form1. Clicking the button opens up Form2, on which you have another Button. Clicking this button on Form2 should change the background color of the label on Form1. So our setup would look like this. You haven't mentioned if it's Winforms or WPF, so I'm using WPF for my convenience but the idea is the same in either.
Form1
Form2
In my Form1 I'd declare a public delegate with a signature like this:
public delegate void NotifyEvent();
That is, this delegate represents a method that takes in no parameters, and has void return type. The idea is to let Form2 'call' a method in Form1, and that method essentially notifies the button was clicked on Form2. So, if there was a way for us to call a method that resides in the Form1 from Form2, we can then notify Form1 of an event happening on Form2 With me so far?
Now, if I write a method like this in the Form1, and let it be called from Form2, that should accomplish our goal. Here, lblDisp is the Label in Form1.
public void ButtonClickedOnForm2()
{
lblDisp.Background = new SolidColorBrush(Colors.LawnGreen);
}
To accomplish this, I would define a delegate of type NotifyEvent in Form1 like below, and register the ButtonClickedOnForm2() method to it. Your Form1 code behind should look like this
public delegate void NotifyEvent();
public partial class Form1 : Window
{
public NotifyEvent notifyDelegate;
Form2 form2 = null;
public Form1()
{
InitializeComponent();
// This is 'registering' the ButtonClickedOnForm2 method to the delegate.
// So, when the delegate is invoked (called), this method gets executed.
notifyDelegate += new NotifyEvent(ButtonClickedOnForm2);
}
public void ButtonClickedOnForm2()
{
lblDisp.Background = new SolidColorBrush(Colors.LawnGreen);
}
private void BtnOpen_Click(object sender, RoutedEventArgs e)
{
// Passing the delegate to `Form2`
form2 = new Form2(notifyDelegate);
form2.Show();
}
}
Accordingly, now we need to modify our Form2. We need to tell us which delegate to invoke when the button click happens. So to do that, I'd pass the delegate in the constructor of Form2 like so:
public partial class Form2 : Window
{
NotifyEvent notifyDel;
public Form2(NotifyEvent notify)
{
InitializeComponent();
notifyDel = notify;
}
private void BtnOK_Click(object sender, RoutedEventArgs e)
{
// This invokes the delegate, which in turn calls the ButtonClickedOnForm2 method in Form1.
notifyDel.Invoke();
}
}
Now, when the button is clicked on Form2, it invokes the delegate. And on our Form1, we've told it that in case the delegate is invoked, it should go ahead and execute the ButtonClickedOnForm2 method. In that method, we've written code to change the background color of the label. And that should solve your problem.
Passing Data
Additionally, if you want to pass data from Form2 to Form1, you can simply add parameters to the delegate definition. Say you want to pass a string from Form2 to Form1. Then, you'd change your delegate to look like this:
public delegate void NotifyEvent(string data);
And the method ButtonClickedOnForm2 like so:
public void ButtonClickedOnForm2(string data)
{
lblDisp.Content = data;
lblDisp.Background = new SolidColorBrush(Colors.LawnGreen);
}
Then on Form2, invoke the delegate by passing a string like so:
private void BtnOK_Click(object sender, RoutedEventArgs e)
{
// This invokes the delegate, which in turn calls the ButtonClickedOnForm2 method in Form1.
notifyDel.Invoke("I am from Form2");
}
Now clicking the button on Form2 should change text and background color of label on Form1 like this:
With Form f1 = new Form(); you are creating a new form instead of accessing one which is already open and you don't call f1.Show(); therefore it will never be displayed. You need a reference to the one which is open. E.g. pass form 1 as constructor parameter to form 2.
In form 2:
public partial class Form2 : Form
{
private readonly Form1 _form1;
public Form2 (Form1 from1)
{
_form1 = form1;
InitializeComponent();
}
public void button1_Click(object sender, EventArgs e)
{
_form1.label2.ForeColor = Color.Red;
}
}
In form 1:
// Cannot be static as we need a reference to `this`
private Form2 _f2;
public Form2 f2 {
get {
if (_f2 == null) {
_f2 = new Form2(this); // Pass form 1 as parameter to form 2.
}
return _f2;
}
}
private void addButton1_Click(object sender, EventArgs e)
{
f2.Show();
}
Thank you for constructor idea. Anyway (this) does not work for me in global scope. So I needed to simplify it to this:
Form 2 with constructor:
public Form1 _form1 { get; set; }
public Form2(Form1 form1)
{
_form1 = form1;
InitializeComponent();
}
public void button1_Click(object sender, EventArgs e)
{
_form1.label2.ForeColor = Color.Red;
}
}
Form 1 creating new object with parameter everytime call needed(because of 'this'):
private void addButton1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2(this);
f2.Show();
}
Works fine so far...
try this code
Form1:
private void addbutton1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2(this);
f2.Show();
}
public void ColorChange()
{
label2.ForeColor = Color.Red;
}
Form2:
public Form1 f1;
public Form2(Form1 m)
{
this.f1 = m;
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
f1.Show();
f1.ColorChange();
}
I have two forms in my program. I have a textbox and a button in both of them. when I click on button in form1, form2 is displayed using showdialog();
When I type in textbox in form2 and click on the button in this form, form2 closes and focus is on form1 and the text that I type in form2 is transferred to a textbox on form1.
How should I do this?
Hold a reference in form1 to the instance of form2 that is being shown as a dialog
Expose a public property in form2 giving the contents of the textbox in form2
When form2 closes, the next line of code should access this property and use its value to populate the textbox in form1,
Something like:
Window form2 = new Form2();
form2.ShowDialog();
this.textBox1 = form2.TextBoxValue;
Where form2 has a property defined:
public string TextBoxValue {
get { return textBox2.Text; }
}
If you don't care about security, the easiest way would be to declare the TextBox in form1 as public, and then change its text property from form2.
In form2, you must change the textbox modifier property to public. This will make the designer generate a public property for the textbox so you can access it anywhere.
When the form2 closes, you simply do:
myTextbox.Text = form2.textBox1.Text;
try this:
(In order)
on Form1:
private void button1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.Showdialog();
this.Hide();
}
then Form2:
private void button1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2(textBox2.Text);
frm2.Showdialog();
this.Hide();
}
then form1:
public partial class Form1 : Form
{
public string textBoxValue;
public Form1()
{
InitializeComponent();
}
public Form1(string textBoxValue)
{
InitializeComponent();
this.textBoxValue = textBoxValue;
}
private void Form1_Load(object sender, EventArgs e)
{
textBox1.Text = textBoxValue;
}
I have created two forms in C# using "Add new item". Form1 is my default opening form. I'm using the following code to switch to form2:
Form1 class:
Form form2= new form2();
this.Hide();
form2.Show();
Form2 class:
what should i do here to open the same form1 again without creating the new instant of form1?
You should pass an instance of this to form2 and have it .Show() it when the time comes.
A simple solution could be showing the second form modally, then making the first form visible when the second form closes, like this:
public partial class Form1: Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
this.Hide();
form2.ShowDialog();
this.Show();
}
}
public partial class Form2: Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Close();
}
}
Making this work non-modally is left as an exercise :)
When you are doing form2.hide() you are actually hiding not destroying it
so the instance you have created still exist so you can use to show it again
if you use form2.dispose() then you have to create a new instance
In the form2 code behind, add parameter in constructor
Form2(Form form1)
{
//use form1 object here
//you can declare a variable of Form1 in Form2 and use it everywhere in the scope of form2
}
Then while initialising object of form2:
Form form2 = new Form(this);
this.Hide();
form2.show();
I am trying to get access to Form1’s public method on another form Form2 as below. I have a textbox6 control on form1 and there is public method to bind it. But I want to bind it by form2 as below.
Form1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.Show();
}
public void amount_sum()
{
string connstr = " server=.;initial catalog=maa;uid=mah;pwd=mah";
SqlConnection con = new SqlConnection(connstr);
con.Open();
string sql = " select sum(amount)as amount from method";
SqlDataAdapter dap = new SqlDataAdapter(sql, con);
DataSet ds = new DataSet();
dap.Fill(ds);
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
textBox6.Text = Convert.ToString(ds.Tables[0].Rows[i]["amount"]);
}
}
}
Form2
private void button1_Click(object sender, EventArgs e)
{
Form1 f1 = new Form1();
f1.amount_sum();
this.Close();
}
The above method-call is wrong. Please suggest how to correct it.
I want to bind Form1’s textBox6 control from Form2's Button_Click event-handler by calling the public method, and when Form2 is closed, then Form1’s textbox6 should be bound. Is that possible by calling the public method from Form2?
In Form2 you have
Form1 f1 = new Form1();
f1.amount_sum();
This seems to be a common mistake to create a new Form1 when you want to pass the answer back between forms. The new keyword does just that, it creates a new Form1, calls the method, does not show the form, the original instance of Form1 is unaffected.
I'll show some steps how to fix this.
1 - Pass Form1 to Form2
The first thing you can do is to simply pass the existing Form1 to Form2 so that Form2 know which Form1 it should update.
public class Form2
{
private readonly Form1 _form1;
public Form2(Form1 form1)
{
_form1 = form1;
}
private void button1_Click(object sender, EventArgs e)
{
_form1.amount_sum(); // now this updates the existing form1 instance
this.Close();
}
}
In Form1
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2(this); // pass this form1 instance to form2
f2.Show();
}
One issue with this is that is creates a strong coupling between Form1 and Form2. If you change something in Form1 it is easy to break Form2 and the other way around.
2 - Pass a delegate
Instead of passing the whole Form1 to Form2 we can simple pass a delegate to an update method that Form2 can run. This creates less coupling between Form1 and Form2, if you call Form2 from Form3 you can pass in the update method of Form3 instead and Form3 will be updated. The same Form2 can be reused without modification.
public class Form2
{
private readonly Action _ammountUpdater;
public Form2(Action ammountUpdater)
{
_ammountUpdater = ammountUpdater;
}
private void button1_Click(object sender, EventArgs e)
{
_ammountUpdater(); // now this updates the existing form1 instance
this.Close();
}
}
In Form1
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2(this.amount_sum); // pass the update method to form2
f2.Show();
}
Now you can change amount_sum to private since it is now really an internal affair of Form1.
I would make your amount_sum method a utility method that returns the value, for example:
public static decimal GetTotalFoobarAmount()
{ // decimal is just a guess here
// omitted: sql code
return theAnswer;
}
Then both blocks of code can call this method, for example.
textBox6.Text = YourClass.GetTotalFoobarAmount().ToString();
As a side-benefit, it also reduces coupling between your UI and DB, which is generally considered a good thing. If the query requires values currently from the form, make those parameters in the method. Note also that for returning a single value you might want to look at ExecuteScalar; it isn't going to make a massive difference, but it is more direct than populating a DataTable and looping over the single row.
Also you may use events:
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.ButtonClickAction += f2_ButtonClickAction;
f2.Show();
}
void f2_ButtonClickAction()
{
amount_sum();
}
Form2:
public Form2()
{
InitializeComponent();
}
public event Action ButtonClickAction;
private void button1_Click(object sender, EventArgs e)
{
Action a = ButtonClickAction;
if (a != null)
a();
this.Close();
}
Marc Gravell's answer is probably sufficient, but in general, if you want to call an instance method on a specific instance of a class, you can't just create a new one and call it on that instance. For your example, you need to call the method on the Form1 instance that already exists. The best way to do that is to have a member variable on the Form2 class of type Form1. You can define a constructor or a property on Form2 which takes a value of type Form1 and set the member variable in it. When Form1 creates an instance of Form2, it can call the constructor and pass in this or set the property to this. Then when the button is clicked on Form2, instead of creating a new instance of Form1, it can call the amount_sum() method on the Form1 instance that is already stored.