I am new to c#. I have the following in my project in windows forms:
Form1 with button and DataGridView.
Form2 with button.
Form3 with button and 3 textBoxes.
As shown in the screenshot In form1, I click buttonOpenForm2 form2 pops up. Then in form2 I click buttonOpenForm3 form3 pops up which has 3 text boxes and button. Now the 3 forms are open.
I enter values in textBox1, textBox2 and textBox3 and when click buttonAddRow ( from form3) I want these values to be inserted into the DataGRidView in Form1.
My question is:
How can I add a row into DataGridView in Form1 ( parent) from form3 (child of child form) WITHOUT closing form2 and form3? I mean I want to pass the data while form2 and form3 are still open.
Please help me. Thank you
Form1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void buttonOpenForm2 _Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.Show();
}
}
Form2:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void buttonOpenForm3 _Click(object sender, EventArgs e)
{
Form3 frm3 = new Form3();
frm3.Show();
}
}
Form3:
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
private void buttonAddRow _Click(object sender, EventArgs e)
{
//What to write here to insert the 3 textboxes values into DataGridView?
}
}
You cannot expect to get complete code that's ready to be pasted. I quickly wrote this in notepad to give you idea about how events work best in such cases. I assumed Form1 directly opens Form3. Solution below shows how to use events.
You home work is to make it work by adding another form Form2 in between. You can do so by propagating same event via Form2 which sits in middle.
Form3.cs
public partial class Form3 : Form
{
public event EventHandler<AddRecordEventArgs> RecordAdded
public Form3()
{
InitializeComponent();
}
private void buttonAddRow _Click(object sender, EventArgs e)
{
OnRecordAdded();
}
private void OnRecordAdded() {
var handler = RecordAdded;
if(RecordAdded != null) {
RecordAdded.Invoke(this, new AddRecordEventArgs(txtQty.Text, txtDesc.Text, txtPrice.Text))
}
}
}
AddRecordEventArgs.cs
public class AddRecordEventArgs : EventArgs
{
public AddRecordEventArgs(string qty, string desc, string price) {
Quantity = qty;
Description = desc;
Price = price;
}
public int Quantity { get; private set; }
public string Description { get; private set; }
public decimal Price { get; private set; }
}
Form1.cs
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void buttonOpenForm3_Click(object sender, EventArgs e)
{
Form3 frm3 = new Form3();
frm3.RecordAdded += Form3_RecordAdded;
frm3.Show();
}
private void Form3_RecordAdded(object sender, AddRecordEventArgs e) {
// Access e.Quantity, e.Description and e.Price
// and add new row in grid using these values.
}
}
1 Solution
You can use pattern with sending data further by constructor (special setter before Show method) and getting them back after window is closed by public getter.
public partial class Form2 : Form
{
Data Data1 {get; set;}
//Instead of Data you can pass Form1 class as parametr.
//But this might lead to unreadable code, and using too mutch methods and fields that could be private, public
public Form2(Data data)
{
InitializeComponent();
Data1 = data;
}
private void buttonOpenForm3 _Click(object sender, EventArgs e)
{
//Repeat pattern
Form3 frm3 = new Form3(Data1);
frm3.Show();
}
}
Optionally you dont have to call 3rd window constuctor. Just create Instance of third window store it in first form and just Show it by calling first instance you passed with data. But this might be bad practice in larger scale.
2 Solution
You can use singleton pattern. Create Instance of an first form inside constructor of first form and use it in third form. But you would need to ensure that there will be no more then one and always one instance of this object in memory.
You can pass owner to method Show() for new forms. Then you can get owner form from Owner property.
private void buttonOpenForm2 _Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.Show(this);
}
So you can get Form1:
(Form1)frm2.Owner
and call public method of Form1 class and pass there your new data.
I want to pass values between two Forms (c#). How can I do it?
I have two forms: Form1 and Form2.
Form1 contains one button. When I click on that button, Form2 should open and Form1 should be in inactive mode (i.e not selectable).
Form2 contains one text box and one submit button. When I type any message in Form2's text box and click the submit button, the Form2 should close and Form1 should highlight with the submitted value.
How can i do it? Can somebody help me to do this with a simple example.
There are several solutions to this but this is the pattern I tend to use.
// Form 1
// inside the button click event
using(Form2 form2 = new Form2())
{
if(form2.ShowDialog() == DialogResult.OK)
{
someControlOnForm1.Text = form2.TheValue;
}
}
And...
// Inside Form2
// Create a public property to serve the value
public string TheValue
{
get { return someTextBoxOnForm2.Text; }
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2(textBox1.Text);
frm2.Show();
}
public Form2(string qs)
{
InitializeComponent();
textBox1.Text = qs;
}
Define a property
public static class ControlID {
public static string TextData { get; set; }
}
In the Form1
private void button1_Click(object sender, EventArgs e)
{
ControlID.TextData = txtTextData.Text;
}
Getting the data in Form1 and Form2
private void button1_Click(object sender, EventArgs e)
{
string text= ControlID.TextData;
}
After a series of struggle for passing the data from one form to another i finally found a stable answer. It works like charm.
All you need to do is declare a variable as public static datatype 'variableName' in one form and assign the value to this variable which you want to pass to another form and call this variable in another form using directly the form name (Don't create object of this form as static variables can be accessed directly) and access this variable value.
Example of such is,
Form1
public static int quantity;
quantity=TextBox1.text; \\Value which you want to pass
Form2
TextBox2.Text=Form1.quantity;\\ Data will be placed in TextBox2
Declare a public string in form1
public string getdata;
In button of form1
form2 frm= new form2();
this.hide();
form2.show();
To send data to form1 you can try any event and code following in that event
form1 frm= new form1();
form1.getdata="some string to be sent to form1";
Now after closing of form2 and opening of form1, you can use returned data in getdata string.
I've worked on various winform projects and as the applications gets more complex (more dialogs and interactions between them) then i've started to use some eventing system to help me out, because management of opening and closing windows manually will be hard to maintain and develope further.
I've used CAB for my applications, it has an eventing system but it might be an overkill in your case :) You could write your own events for simpler applications
Form1 Code :
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.ShowDialog();
MessageBox.Show("Form1 Message :"+Form2.t.Text); //can put label also in form 1 to show the value got from form2
}
Form2 Code :
public Form2()
{
InitializeComponent();
t = textBox1; //Initialize with static textbox
}
public static TextBox t=new TextBox(); //make static to get the same value as inserted
private void button1_Click(object sender, EventArgs e)
{
this.Close();
}
It Works!
declare string in form1
public string TextBoxString;
in form1 click event add
private void button1_Click(object sender, EventArgs e)
{
Form1 newform = new Form1();
newform = this;
this.Hide();
MySecform = new Form2(ref newform);
MySecform.Show();
}
in form2 constructer
public Form2(ref Form1 form1handel)
{
firstformRef = form1handel;
InitializeComponent();
}
in form2 crate variable Form1 firstformRef;
private void Submitt_Click(object sender, EventArgs e)
{
firstformRef.TextBoxString = textBox1.Text;
this.Close();
firstformRef.Show();
}
In this code, you pass a text to Form2. Form2 shows that text in textBox1.
User types new text into textBox1 and presses the submit button.
Form1 grabs that text and shows it in a textbox on Form1.
public class Form2 : Form
{
private string oldText;
public Form2(string newText):this()
{
oldText = newText;
btnSubmit.DialogResult = DialogResult.OK;
}
private void Form2_Load(object sender, EventArgs e)
{
textBox1.Text = oldText;
}
public string getText()
{
return textBox1.Text;
}
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
DialogResult = System.Windows.Forms.DialogResult.OK;
}
}
}
And this is Form1 code:
public class Form1:Form
{
using (Form2 dialogForm = new Form2("old text to show in Form2"))
{
DialogResult dr = dialogForm.ShowDialog(this);
if (dr == DialogResult.OK)
{
tbSubmittedText = dialogForm.getText();
}
dialogForm.Close();
}
}
Ok so Form1 has a textbox, first of all you have to set this Form1 textbox to public in textbox property.
Code Form1:
Public button1_click()
{
Form2 secondForm = new Form2(this);
secondForm.Show();
}
Pass Form1 as this in the constructor.
Code Form2:
Private Form1 _firstForm;
Public Form2(Form1 firstForm)
{
_firstForm = firstForm:
}
Public button_click()
{
_firstForm.textBox.text=label1.text;
This.Close();
}
you can pass as parameter the textbox of the Form1, like this:
On Form 1 buttom handler:
private void button2_Click(object sender, EventArgs e)
{
Form2 newWindow = new Form2(textBoxForReturnValue);
newWindow.Show();
}
On the Form 2
public static TextBox textBox2; // class atribute
public Form2(TextBox textBoxForReturnValue)
{
textBox2= textBoxForReturnValue;
}
private void btnClose_Click(object sender, EventArgs e)
{
textBox2.Text = dataGridView1.CurrentCell.Value.ToString().Trim();
this.Close();
}
Constructors are the best ways to pass data between forms or Gui Objects you can do this.
In the form1 click button you should have:
Form1.Enable = false;
Form2 f = new Form2();
f.ShowDialog();
In form 2, when the user clicks the button it should have a code like this or similar:
this.Close();
Form1 form = new Form1(textBox1.Text)
form.Show();
Once inside the form load of form 1 you can add code to do anything as you get the values from constructor.
How to pass the values from form to another form
1.) Goto Form2 then Double click it. At the code type this.
public Form2(string v)
{
InitializeComponent();
textBox1.Text = v;
}
2.) Goto Form1 then Double click it. At the code type this.
//At your command button in Form1
private void button1_Click(object sender, EventArgs e)
{
Form2 F2 = new Form2(textBox1.Text);
F2.Show();
}
This is very simple.
suppose you have 2 window form Form1 and Form2 and you want to send record of textbox1 from Form1 to Form2 and display this record in label1 of Form2;
then in Form2 create a label which name is label1 and go to the property of label1 and set 'Modifiers'=public and in Form one create a textBox with id textBox1 and a button of name submit then write the following code on button click event
button1_Click(object sender, EventArgs e)
{
Form2 obj=new Form2();
obj.label1.text=textBox1.text.ToString();
obj.show();
}
thats it...
for this way you can bind dataset record to another form's datagridview......
You can make use of a different approach if you like.
Using System.Action (Here you simply pass the main forms function as the parameter to the child form like a callback function)
OpenForms Method ( You directly call one of your open forms)
Using System.Action
You can think of it as a callback function passed to the child form.
// -------- IN THE MAIN FORM --------
// CALLING THE CHILD FORM IN YOUR CODE LOOKS LIKE THIS
Options frmOptions = new Options(UpdateSettings);
frmOptions.Show();
// YOUR FUNCTION IN THE MAIN FORM TO BE EXECUTED
public void UpdateSettings(string data)
{
// DO YOUR STUFF HERE
}
// -------- IN THE CHILD FORM --------
Action<string> UpdateSettings = null;
// IN THE CHILD FORMS CONSTRUCTOR
public Options(Action<string> UpdateSettings)
{
InitializeComponent();
this.UpdateSettings = UpdateSettings;
}
private void btnUpdate_Click(object sender, EventArgs e)
{
// CALLING THE CALLBACK FUNCTION
if (UpdateSettings != null)
UpdateSettings("some data");
}
OpenForms Method
This method is easy (2 lines). But only works with forms that are open.
All you need to do is add these two lines where ever you want to pass some data.
Main frmMain = (Main)Application.OpenForms["Main"];
frmMain.UpdateSettings("Some data");
I provided my answer to a similar question here
You can use this;
Form1 button1 click
private void button1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
this.Hide();
frm2.Show();
}
And add this to Form2
public string info = "";
Form2 button1 click
private void button1_Click(object sender, EventArgs e)
{
info = textBox1.Text;
this.Hide();
BeginInvoke(new MethodInvoker(() =>
{
Gogo();
}));
}
public void Gogo()
{
Form1 frm = new Form1();
frm.Show();
frm.Text = info;
}
if you change Modifiers Property of a control in a Form to Public, another Forms can access to that control.
f.e. :
Form2 frm;
private void Form1_Load(object sender, EventArgs e)
{
frm = new Form2();
frm.Show();
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(frm.txtUserName.Text);
//txtUserName is a TextBox with Modifiers=Public
}
// In form 1
public static string Username = Me;
// In form 2's load block
string _UserName = Form1.Username;
the tag Properties receive object value
( C# send value to another form )
private void btn_Send_Click(object sender, EventArgs e)
{
Form frm = new formToSend();
frm.tag = obj;
frm.ShowDialog();
}
Receive value that sent from previous form ( frm )
Ex: sent data is string ( we need to type casting first, because tag value is an object )
public Receive_Form()
{
InitializeComponent();
MessageBox.Show((string)this.Tag);
}
How about using a public Event
I would do it like this.
public class Form2
{
public event Action<string> SomethingCompleted;
private void Submit_Click(object sender, EventArgs e)
{
SomethingCompleted?.Invoke(txtData.Text);
this.Close();
}
}
and call it from Form1 like this.
private void btnOpenForm2_Click(object sender, EventArgs e)
{
using (var frm = new Form2())
{
frm.SomethingCompleted += text => {
this.txtData.Text = text;
};
frm.ShowDialog();
}
}
Then, Form1 could get a text from Form2 when Form2 is closed
Thank you.
This question already has answers here:
Communicate between two windows forms in C#
(12 answers)
Closed 3 years ago.
I have 2 winforms in my project. When i clicked on "Settings" button on Form1, it shows the Settings form, I'm making some changes on textboxes and when I click the Save button on second form, it saves these values to a text file and I wanna pass these values to first form, but I couldn't pass them.
Here is some parts of my codes;
This code is Settings button click (on Form1)
private void button3_Click(object sender, EventArgs e)
{
Settings frm = new Settings();
frm.Show();
}
public void funData(TextBox txtForm1)
{
label3.Text = txtForm1.Text;
}
and this code is Save button click (Second form)
private void button5_Click(object sender, EventArgs e)
{
if (File.Exists(ConfigFile))
{
File.Delete(ConfigFile);
using (StreamWriter writer = new StreamWriter(ConfigFile))
{
writer.WriteLine(txtTemsPath.Text);
writer.WriteLine(txtVodafonePath.Text);
writer.WriteLine(txtTurkcellPath.Text);
writer.WriteLine(txtAveaPath.Text);
writer.Close();
}
}
else
{
using (StreamWriter writer = new StreamWriter(ConfigFile))
{
writer.WriteLine(txtTemsPath.Text);
writer.WriteLine(txtVodafonePath.Text);
writer.WriteLine(txtTurkcellPath.Text);
writer.WriteLine(txtAveaPath.Text);
writer.Close();
}
}
Form1 frm = new Form1();
delPassData del = new delPassData(frm.funData);
del(this.txtTemsPath);
frm.getSettings();
frm.TemsPath = TemsPath;
frm.Activate();
frm.Refresh();
this.Close();
}
Could you please help me for this issue?
Thanks
define on your first Form:
Settings obj = (Settings)Application.OpenForms["Settings"];
private void button3_Click(object sender, EventArgs e)
{
Settings obj = new Settings();
obj.Show();
}
And replace in your code anywhere else frm with obj
The thing is that you must refer each time to the current instance of the other form and not open a new one
You need to create a public property accessor on form2 with the data you would like to store. After form2 closes you will still be able to access this data by using form2.MySpecialData as long as you havent nullified it. this question has been asked many times on stackoverflow and there are alot of good examples.
Communicate between two windows forms in C#
public Form2()
{
InitializeComponent();
}
private string mySpecialData;
public string MySpecialData
{
get { return mySpecialData; }
set { mySpecialData = value; }
}
Add a property to Settings to return the "TemsPath" value. Then, instead of Close(), set DialogResult to OK:
public partial class Settings : Form
{
public string TemsPath
{
get { return txtTemsPath.Text; }
}
private void button5_Click(object sender, EventArgs e)
{
// ... your save code ...
this.DialogResult = System.Windows.Forms.DialogResult.OK;
}
}
Now, back in Form1, use ShowDialog() instead of Show() and access the property when it returns:
public partial class Form1 : Form
{
private void button3_Click(object sender, EventArgs e)
{
Settings frm = new Settings();
if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
label3.Text = frm.TemsPath;
}
}
}
I am new to C# and already starting to have some troubles. I have googled for some hours how to get this done but my program refuses to obey his master.
My MainForm has a ListBox. Form2 uses a Open File Dialog and should return the file path to the ListBox in MainForm
This is the code I have in Form2
public void BrowseFileDialog_FileOk(object sender, CancelEventArgs e)
{
string path = BrowseFileDialog.FileName;
MainForm frm = new MainForm();
frm.AppListAdd(path);
}
This is the MainForm
public void AppListAdd (string path)
{
AppList.Items.Add(path);
}
Note: AppList = ListBox
I don't get any error, yet the ListBox remains empty.
You are creating a new instance of MainForm and not showing it, while the visible/existing/real main form is not affected.
Add to Form2 class:
public MainForm MainForm { get; set; }
When you create Form2 do (presumably in a MainForm's method):
Form2 form2 = new Form2();
form2.MainForm = this;
and
public void BrowseFileDialog_FileOk(object sender, CancelEventArgs e)
{
string path = BrowseFileDialog.FileName;
if (MainForm != null)
MainForm.AppListAdd(path);
}
In my app in several time i have to call a window(class). the work of this window is to show the meaning of a word.when i again call that window a new window shows but the previous one also shows.
I have two form named form1,form2.
Form1 is like that:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string a = textBox1.Text;
Form2 s = new Form2(a);// it will be called as many time as i click
s.Show();
}
}
Form2 is like that:
public partial class Form2 : Form
{
public Form2(string s)
{
InitializeComponent();
label1.Text = s;
}
}
what i want is that inside form1 if i call form2 it shows but if i call form2 again the previous form2 window will be closed automatically and new form2 window will be shown instead of previous one.
How can i do that????
Here's an example of storing the Form2 reference at class level, as mentioned by the others already:
public partial class Form1 : Form
{
private Form2 f2 = null;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (f2 != null && !f2.IsDisposed)
{
f2.Dispose();
}
string a = textBox1.Text;
f2 = new Form2(a);
f2.Show();
}
}
I think you should consider using singleton pattern.
You can implement it like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string a = textBox1.Text;
Form2.ShowMeaning(a);// it will be called as many time as you click
}
}
and Form2
public partial class Form2 : Form
{
private static readonly Form2 _formInstance = new Form2();
private Form2()
{
InitializeComponent();
}
private void LoadMeaning(string s)
{
label1.Text = s;
}
//Override method to prevent disposing the form when closing.
protected override void OnClosing(CancelEventArgs e)
{
e.Cancel = true;
this.Hide();
}
public static void ShowMeaning(string s)
{
_formInstance.LoadMeaning(s);
_formInstance.Show();
}
}
Hope it helps.