I hope the title is clear enough. Let me explain : I am doing a c# Winform App. When I start the app I have my Form 1 which starts, and I have other forms I can open from it by clicking buttons.
The problem is, I have functions in those Forms (Form 2, Form 3, Form 4..) I want to start from the Form 1 .
Currently here's my code
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// First Event, when I click in the toolstrip menu, I open the Form2 ("Ligne3")
private void ligne3ToolStripMenuItem_Click(object sender, EventArgs e)
{
var Ligne3 = new Ligne3();
Ligne3.Show();
}
Then, I have components in the Form2 (textboxs, buttons, functions etc)
public partial class Ligne3 : Form
{
public Ligne3()
{
InitializeComponent();
}
private void Ligne3_Load(object sender, EventArgs e)
{
//Some code
}
}
//Function I want to call from the Form1
public void send_email()
{
//Some code
}
How can I start my " send_email() " function from the Form1 (for example during Load Event) ?
Assign the values of Form2 or any other objects/variables to Linge3 object before calling show. Values which are needed in send_email() to be assigned before calling send_email(). Something like below.
private void ligne3ToolStripMenuItem_Click(object sender, EventArgs e)
{
var ligne3 = new Ligne3();
//define variables/properties in Ligne3 for all values to be passed
//then assign them with corresponding values
ligne3.Value1 = objForm2.Value1;
ligne3.Value2 = objForm2.Value2;
ligne3.Value3 = objForm2.textBox1.Text;
ligne3.Value3 = objForm2.checkBox1.Value;
//and so on
ligne3.send_email();
ligne3.Show();
}
If you are clicking a buttons on Form1, to start and open forms 2,3,4 etc, and in those btn_click handlers you are creating a new form2, 3,3,4. Then you will have a reference to each form and and can therefore just call the respective public method on the instance just created. eg
public class Form1
{
private Form2 subForm2;
private void OpenForm2_Click(object sender, eventargs e)
{
subForm2 = new Form2();
subForm2.Show()
}
private void sendEmailBtn_Click(object sender, EventArgs e)
{
subForm2.Send_email();
}
}
This are many things wrong with the above from a design point of view but i'm just using it to present the idea.
If you are creating the instance of Form2,3,4 etc outside of Form1's instantiation, then you would need some form of Constructor or property injection to provide the instance references.
Related
This question already has answers here:
Communicate between two windows forms in C#
(12 answers)
Closed 6 years ago.
hey everyone I am currently trying to refresh a form once changes are done on a second. On my first form I press a button "create" that will open another form, form2. This second form will have input fields and allows you to input values that populate comboboxes on the first form. On the second form there is a button "update" I would like the fist form to refresh once update is pressed on the first.
I know there is this.refresh();, but I'm not sure if this is useful for me. I am trying to something along the lines of:
On form2 -
Private void Form2UpdateButton_Click
{
//do update stuff
Form1_load.Refresh();
}
or maybe
private void Form2UpdateButton_Click
{
//do update stuff
Form1.close();
Form1.Open();
}
I am still pretty new to C# and interacting 2 forms together is a rather complex concept to me so please let me know if I am going about this the wrong way. My refresh may be in the wrong spot, but I think this is what I want.
Create an own event on form2 that triggers when the button gets clicked. This way you can just form2.OnUpdateClicked += yourMethod. Like this:
public partial class Form1 : Form
{
private void CreateForm2()
{
Form2 frm2 = new Form2();
// Hook the event of form2 to a method
frm2.PropertyUpdated += Form2Updated;
}
private void Form2Updated(object sender, EventArgs e)
{
// this will be fired
}
}
public partial class Form2 : Form
{
// On form2 create an event
public event EventHandler PropertyUpdated;
private void Form2UpdateButton_Click()
{
// If not null (e.g. it is hooked somewhere -> raise the event
if(PropertyUpdated != null)
PropertyUpdated(this, null);
}
}
Recommendations:
Your second form should be created with a reference to first one, ie,
Form1:
public void RefreshParameters()
{
// ... do your update magic here
}
private void openForm2(..)
{
// Pass your current form instance (this) to new form2
var aForm = new Form2(this);
aForm.Show(); // show, run, I don't remember... you have it
}
Form2:
// Here you will store a reference to your form1
form1 daddy = null;
// A new constructor overloading default one to pass form1
public Fomr2(Form1 frm):base()
{
daddy = frm; // Here you store a reference to form1!
}
public void UpdateDaddy()
{
// And here you can call any public function on form1!
frm.RefreshParameters();
}
One way is to pass a reference of Form1 to Form2, like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void buttonLaunchForm_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.LauncherForm = this;
form2.Show();
}
public void RefreshFormData()
{
// Refresh
}
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public Form1 LauncherForm { set; get; }
private void buttonUpdate_Click(object sender, EventArgs e)
{
// do your normal work then:
LauncherForm.RefreshFormData();
}
}
The above technique is called "Property-Injection";
I have a form 1 and form 2 in window form C#.in from 1 i have tabcontrol and function of add new tab , detect , and active tab which work fine in form 1 but not show any the in form 2.
public void add_tab(string str)
{
TabPage myTabPage = new TabPage(str);
myTabPage.Name = str;
tabControl1.TabPages.Add(myTabPage);
}
private void button2_Click(object sender, EventArgs e)
{
active_tab(textBox1.Text);
}
public void active_tab(string st)
{
tabControl1.SelectTab(st);
}
private void button3_Click(object sender, EventArgs e)
{
delect(textBox1.Text);
}
public void delect(string st)
{
tabControl1.TabPages.RemoveByKey(st);
}
I think, you want to be able to access tabcontrol from form1 in form2's code behind.
In that case, you either Pass the reference of form1 to form2, This can be done in multiple ways.
var form1 = new Form1();
..
var form2 = new Form2(form1);
Now using Form2 reference you can access tabcontrol.
Hope this was the issue you were facing.
This question already has answers here:
Communicate between two windows forms in C#
(12 answers)
Closed 3 years ago.
I am struggling to work out how to pass values between forms. I have four forms and I want to pass the information retrieved by the Login to the fourth and final form.
This is what I have so far.
In this function:
private void btnLogin_Click(object sender, EventArgs e)
I have deserialized the data I want like this:
NewDataSet resultingMessage = (NewDataSet)serializer.Deserialize(rdr);
Then, when I call the next form I have done this:
Form myFrm = new frmVoiceOver(resultingMessage);
myFrm.Show();
Then, my VoiceOver form looks like this:
public frmVoiceOver(NewDataSet loginData)
{
InitializeComponent();
}
private void btnVoiceOverNo_Click(object sender, EventArgs e)
{
this.Close();
Form myFrm = new frmClipInformation();
myFrm.Show();
}
When I debug, I can see the data is in loginData in the second form, but I cannot seem to access it in the btnVoiceOverNo_Click event. How do I access it so I can pass it to the next form?
You need to put loginData into a local variable inside the frmVoiceOver class to be able to access it from other methods. Currently it is scoped to the constructor:
class frmVoiceOver : Form
{
private NewDataSet _loginData;
public frmVoiceOver(NewDataSet loginData)
{
_loginData = loginData;
InitializeComponent();
}
private void btnVoiceOverNo_Click(object sender, EventArgs e)
{
// Use _loginData here.
this.Close();
Form myFrm = new frmClipInformation();
myFrm.Show();
}
}
Also, if the two forms are in the same process you likely don't need to serialize the data and can simply pass it as a standard reference to the form's constructor.
Google something like "C# variable scope" to understand more in this area as you will encounter the concept all the time. I appreciate you are self-taught so I'm just trying to bolster that :-)
In various situations we may need to pass values from one form to another form when some event occurs. Here is a simple example of how you can implement this feature.
Consider you have two forms Form1 and Form2 in which Form2 is the child of Form1. Both of the forms have two textboxes in which whenever the text gets changed in the textbox of Form2, textbox of Form1 gets updated.
Following is the code of Form1
private void btnShowForm2_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.UpdateTextBox += new EventHandler<TextChangeEventArgs>(txtBox_TextChanged);
form2.ShowDialog();
}
private void txtBox_TextChanged(object sender, TextChangeEventArgs e)
{
textBox1.Text = e.prpStrDataToPass;
}
Following is the code of Form2
public event EventHandler<TextChangeEventArgs> UpdateTextBox;
private string strText;
public string prpStrText
{
get { return strText; }
set
{
if (strText != value)
{
strText = value;
OnTextBoxTextChanged(new TextChangeEventArgs(strText));
}
}
}
private void textBox_Form2_TextChanged(object sender, EventArgs e)
{
prpStrText = txtBox_Form2.Text;
}
protected virtual void OnTextBoxTextChanged(TextChangeEventArgs e)
{
EventHandler<TextChangeEventArgs> eventHandler = UpdateTextBox;
if (eventHandler != null)
{
eventHandler(this, e);
}
}
In order to pass the values we should store your data in a class which is derived from EventArgs
public class TextChangeEventArgs : EventArgs
{
private string strDataToPass;
public TextChangeEventArgs(string _text)
{
this.strDataToPass = _text;
}
public string prpStrDataToPass
{
get { return strDataToPass; }
}
}
Now whenever text changes in Form2, the same text gets updated in textbox of Form1.
I have 2 forms which consist of:
Form1:
2buttons named:
btnCopy and
btnPaste
(with functions inside like rtb.Copy(); and rtb.Paste(); that should work for richtextbox in Form2)
Form2:
1richtextbox named: rtb
My question was:
How can I communicate between the 2buttons from Form1 (with its functions) and the richtextbox in Form2.
like: When I type text inside richtextbox(rtb) in Form2 then i SelectAll text then I Press the CopyButton(btnCopy) from Form1, text should be copied same as when I Press PasteButton(btnPaste) from Form1, text that has been copied should be Paste in RichTextBox(rtb) that could be Found on Form2 .
How can I do that?
Let's say you have Form1 and ToolStrip Button name PasteToolStripButton like:
public partial class Form1 : Form
{
Form2 formChild;
public Form1()
{
InitializeComponent();
this.Load += new EventHandler(Form1_Load);
}
void Form1_Load(object sender, EventArgs e)
{
formChild = new Form2();
formChild.MdiParent = this;
formChild.Show();
}
private void CopyToolStripButton_Click(object sender, EventArgs e)
{
formChild.CopyText(); // Method to copy Rich Text Box in Form2
}
private void PasteToolStripButton_Click(object sender, EventArgs e)
{
formChild.PasteText(); // Method in Form2 to Paste to the RichTextBox in Form2
}
}
In your Form2 you need to add a Public method named PasteText and CopyText like:
public void PasteText()
{
rtbChild.Text = Clipboard.GetText(); // this one simulates the rtb.Paste()
}
public void CopyText()
{
rtb.Copy();
}
I also named the RichTextBox in Form2 as rtbChild so every time you click for example paste in will be copied in your RichTextBox in Form2.
Create a public property on Form1 then set it from Form2.
EDIT:
On Form1:
public string TextForRTB {get; set;}
On Form2:
Form1 a = new Form1();
a.TextForRtb = rtb.Text;
Sol1: Pass one of the forms to the other, as Form1(Form parent){....} in the constructor, then you should see it's public properties and methods.
Sol2: Create custom events to raise it when text changed on your rich text box, so than the forms that initialized the form with this rich box will do something, like enable/disable a button or something
...Actually, there is a lot of solutions to this kind of behavior, and I wonder why you need to put your text box in a different form from your buttons that seems to be related very closely in business logic together!
You could expose 2 methods GetRichTextBoxContent and SetRichTextBoxContent in Form2.
Which would update the contents of richTextBox in Form2.
Then you could work on the Instance of Form2 form Form1
Note: The major think here is how you get the Instance of Form2. It is up to your implementation to get that instance.
public class Form2 : Form
{
public string GetRichTextBoxContent()
{
return this.richTextBox1.Text;
}
public void SetRichTextBoxContent(string content)
{
this.richTextBox1.Text = content;
}
}
public class Form1 : Form
{
//Based on your implementation
Form2 form2 = new Form2();
private void Button_CopyClick(object sender, EventArgs e)
{
var contentFromRtb = form2.GetRichTextBoxContent();
}
private void Button_PasteClick(object sender, EventArgs e)
{
var someContent = "Content to be copied to text box"
form2.SetRichTextBoxContent(someContent );
}
}
I've a dgv on my main form, there is a button that opens up another form to insert some data into the datasource bounded to the dgv. I want when child form closes the dgv auto refresh. I tried to add this in child form closing event, but it doesn't refresh:
private void frmNew_FormClosing(object sender, FormClosingEventArgs e)
{
frmMain frmm = new frmMain();
frmm.itemCategoryBindingSource.EndEdit();
frmm.itemsTableAdapter.Fill(myDatabaseDataSet.Items);
frmm.dataGridView1.Refresh();
}
However, when I add this code in a button on the parent form, it actually does the trick:
this.itemCategoryBindingSource.EndEdit();
this.itemsTableAdapter.Fill(myDatabaseDataSet.Items);
this.dataGridView1.Refresh();
There are many ways to do this, but the following is the simpliest and it will do what you want and get you started.
Create a public method on your main form.
Modified constructor of second form to take a main form.
Create an instance of the second form passing the main form object.
When closing second form, call the public method of the main form object.
Form1
public partial class Form1 : Form {
public Form1() {
//'add a label and a buttom to form
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
Form2 oForm = new Form2(this);
oForm.Show();
}
public void PerformRefresh() {
this.label1.Text = DateTime.Now.ToLongTimeString();
}
}
Form2
public class Form2 : Form {
Form1 _owner;
public Form2(Form1 owner) {
_owner = owner;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form2_FormClosing);
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e) {
_owner.PerformRefresh();
}
}
We can also proceed this way:
We have form_1 and form_2
In form_1, create a public method. Inside this public method we put our stuff;
In form_2 we create a global form variable;
Still in form_2, pass form_1 into form_2 through form_2 constructor;
Still in form_2, make your global variable(the one we created in step 2) receive the new form_1 instance we created in form_2 constructor;
Inside the closing_event method we call the method which contains our stuff.
The method with our stuff is the method that will fill our form1 list, dataGridView, comboBox or whatever we want.
Form_1:
public fillComboBox()//Step 1. This is the method with your stuff in Form1
{
foreach(var item in collection myInfo)
{myComboBox.Items.Add(item)}
}
Form_2:
Form1 instanceForm1;//Step 2
public Form2(Form1 theTransporter)//Step 3. This the Form2 contructor.
{
InitializeComponent();
instanceForm1 = theTransporter;//Step 4
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
instanceForm1.fillComboBox();//Step 5 we call the method to execute the task updating the form1
}
I hope it helps...
You're creating a new instance of the main form which isn't effecting the actual main form instance. What you need to do is, call the code on the main form itself, just like the code you say works on the button click:
private void frmNew_FormClosing(object sender, FormClosingEventArgs e)
{
this.itemCategoryBindingSource.EndEdit();
this.itemsTableAdapter.Fill(myDatabaseDataSet.Items);
this.dataGridView1.Refresh();
}
Great answer there! The other method would have been:
Check if the form you want to update is open.
Call the method to refresh your gridVieW.
**inside your refreshMethod() in form1 make sure you set the datasource to null **
if (System.Windows.Forms.Application.OpenForms["Form1"]!=null)
{
(System.Windows.Forms.Application.OpenForms["Form1"] as Form1).refreshGridView("");
}