I am passing data between 2 windows forms in c#. Form1 is the main form, whose textbox will receive the text passed to it from form2_textbox & display it in its textbox (form1_textbox).
First, form1 opens, with an empty textbox and a button, on clicking on the form1_button, form2 opens.
In Form2, I entered a text in form2_textbox & then clicked the button (form2_button).ON click event of this button, it will send the text to form1's textbox & form1 will come in focus with its empty form1_textbox with a text received from form2.
I am using properties to implement this task.
FORM2.CS
public partial class Form2 : Form
{
//declare event in form 2
public event EventHandler SomeTextInSomeFormChanged;
public Form2()
{
InitializeComponent();
}
public string get_text_for_Form1
{
get { return form2_textBox1.Text; }
}
//On the button click event of form2, the text from form2 will be send to form1:
public void button1_Click(object sender, EventArgs e)
{
Form1 f1 = new Form1();
f1.set_text_in_Form1 = get_text_for_Form1;
//if subscribers exists
if(SomeTextInSomeFormChanged != null)
{
SomeTextInSomeFormChanged(this, null);
}
}
}
FORM1.CS
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public string set_text_in_Form1
{
set { form1_textBox1.Text = value; }
}
private void form1_button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.Show();
f2.SomeTextInSomeFormChanged +=new EventHandler(f2_SomeTextInSomeFormChanged);
}
//in form 1 subcribe to event
Form2 form2 = new Form2();
public void f2_SomeTextInSomeFormChanged(object sender, EventArgs e)
{
this.Focus();
}
}
Now, in this case I have to again SHOW the form1 in order to automatically get the text in its textbox from form2, but I want that as I click the button on form2, the text is sent from Form2 to Form1, & the form1 comes in focus, with its textbox containing the text received from Form2.
I know this is a (really) old question, but hell..
The "best" solution for this is to have a "data" class that will handle holding whatever you need to pass across:
class Session
{
public Session()
{
//Init Vars here
}
public string foo {get; set;}
}
Then have a background "controller" class that can handle calling, showing/hiding forms (etc..)
class Controller
{
private Session m_Session;
public Controller(Session session, Form firstform)
{
m_Session = session;
ShowForm(firstform);
}
private ShowForm(Form firstform)
{
/*Yes, I'm implying that you also keep a reference to "Session"
* within each form, on construction.*/
Form currentform = firstform(m_Session);
DialogResult currentresult = currentform.ShowDialog();
//....
//Logic+Loops that handle calling forms and their behaviours..
}
}
And obviously, in your form, you can have a very simple click listener that's like..
//...
m_Session.foo = textbox.Text;
this.DialogResult = DialogResult.OK;
this.Close();
//...
Then, when you have your magical amazing forms, they can pass things between each other using the session object. If you want to have concurrent access, you might want to set up a mutex or semaphore depending on your needs (which you can also store a reference to within Session). There's also no reason why you cannot have similar controller logic within a parent dialog to control its children (and don't forget, DialogResult is great for simple forms)
Related
I have 2 forms each with buttons, textboxes, and labels. In form1 I have a this code in a button event handler:
frmTwo form = new frmTwo ();
form.Show();
this.Visible = false; //closing form 1 when frmTwo opens
I went to the designer file for frmTwo and changed all of the controls: labels, textboxes, buttons from private (which was auto generated) to public.
Under this line of code: this.Visible = false; I want to put an if statement to check if a name textbox in frmTwo is blank. But when I write txtName.Text it says the textbox doesn't exist in the current context. I understand why it doesn't exist because its inside frmTwo NOT from1. But I'm not sure what other ways I can access this textbox because I already made it public in the designer. Is there another way to do this?
Ask yourself: Is it important for form1 that the information that you want to read from form2 is in a textbox? Would form1 really care if the same information would be kept by form2 in a ComboBox?
Wouldn't it be best if form1 doesn't know how form2 gets the information? All it has to know is that form2 is willing to provide the information. If form2 needs to read it from a database, or fetch it from the internet to fetch the information, why would form1 care? All form1 wants to know: "Hey Form2, give me information X"
Alas you didn't tell us if you want this information only once, or that form1 needs to be kept informed whenever information X changes. Let's assume that you do.
So, class Form2 will have a method to provide information X, and it is willing to tell everyone that information X is changed. Form2 does not show to the outside world how it gets its information. The current version holds information X in the text of TextBox1. Future versions might read it from a ComboBox, or read if from a file, or from the internet.
class Form2 : System.Windows.Window
{
public event EventHandler XChanged;
public string X
{
// information X is in textBox1
get => this.textBox1.Text;
}
private void TextBox1_Changed(object sender, ...)
{
// the text in textBox1 changed, so information X changed
this.OnXChanged();
}
protected virtual void OnXChanged()
{
this.XChanged?.Invoke(new Eventhandler(this, EventArgs.Empty));
}
... // other Form2 methods
}
Now if Form1 wants to know the value of X, it can simply ask for it:
Form2 form2 = ...
string informationX = form2.X;
If Form1 wants to be kept informed whenever information X changes:
form2.XChanged += InformationXChanged;
private void InformationXChanged(object sender, Eventargs e)
{
Form2 form2 = (Form2)sender;
// get the new information X from form2:
string informationX = form2.X;
this.ProcessInformationX(informationX);
}
If you want one form to replace the other, then you pass a reference to Form1 in the .Show() of Form2 and the form stores it in the .Owner property. The when the second form starts it will hide the first form. Additionally, when the second form closes it can unhide the first form.
Please use Capitalized names for types like Form and pascalCase for variables like mainForm = new Form().
Form1.cs
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var f2 = new Form2();
f2.Show(this);
}
}
Form2.cs
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.FormClosing += Form2_FormClosing;
this.Owner.Visible = false;
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
Owner.Visible = true;
}
public bool IsNameBlank { get => string.IsNullOrWhiteSpace(textBox1.Text); }
}
This is the basic framework. I also added some logic where Form1 checks for a textBox in Form2. Add a property in Form2 that returns the check:
and access it form From1
private void button1_Click(object sender, EventArgs e)
{
var f2 = new Form2();
f2.Show(this);
if (f2.IsNameBlank)
{
// textBox is empty.
}
}
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 created 2 forms (form1 and form2). In form1, press f5 function key it will display form 2. Then I want pass the value to form1 and just close the form2 when button click fire.
Form1 Code
public string fo
{
get { return txtCusID.Text; }
set { txtCusID.Text = value; }
}
Form 2 code
public partial class SearchForm : Form
{
PawningForm f2 =new PawningForm();
private void button1_Click_1(object sender, EventArgs e)
{
lblTest.Text = row.Cells[0].Value.ToString();
f2.fo = lblTest.Text;
f2.Show();
}
}
but when I click button on from2 it will create form1 twice, because "f2.Show();" and existing form1. But I want just pass value to existing form1.
When you create the instance of the SearchForm from the calling form (PawningForm) you could pass the instance of the calling form and keep it in a global variable of the SearchForm, so you code could be changed simply with these lines.
Form 1 code
SearchForm f = SearchForm(this);
f.ShowDialog();
Form 2 code
public partial class SearchForm : Form
{
PawningForm f2;
public void SearchForm(PawningForm caller)
{
f2 = caller;
InitializeComponent();
}
private void button1_Click_1(object sender, EventArgs e)
{
lblTest.Text = row.Cells[0].Value.ToString();
f2.fo = lblTest.Text;
}
}
Now, when you click the button, the instance represented by the variable f2 is not a new instance, but the one that has called the SearchForm instance
So, I have two forms -- one that is open, and another that is essentially just a popup on the second one. The second form opens with a maskedtextbox inside it, plus Save and Cancel buttons -- I want Save to change a field on the first form.
As far as I know, I have to use a second form for my popup since what I want to accomplish isn't as simple as something I could put in a MessageBox -- if there is another option, I'm all ears.
What I've been trying:
Form 1:
public partial class Form1 : Form
{
public void ChangeLabel()
{
label1.Text = StaticVariables.labelString;
}
}
Form 2:
public partial class Form2 : Form
{
private void changeForm1_Click(object sender, EventArgs e)
{
StaticVariables.labelString = textBox.Text;
Form1 frm = new Form1();
frm.ChangeLabel();
}
}
Obviously, that hasn't worked.
There's no need for the second form to know about the first form at all. Having it know about it complicates its code, and needlessly ties it to that form. Having another form knowing about the internal UI components of the main form is even worse; if you do that then changes to how the main form displays the data would break this other form. Just have the popup have a property representing the value that lets it be set/fetched externally:
public partial class Form2 : Form
{
public string Result //TODO give better name
{
get { return textBox.Text; }
}
public string DisplayText //TODO give better name
{
get { return label.Text; }
set { label.Text = value; }
}
}
Then the main form can set the display value, show the form, and fetch the resulting value:
Form2 popup = new Form2();
popup.DisplayText = "asdf";
popup.ShowDialog();
myField = popup.Result;
You need to create a new constructor that receives an instance of Form1 and store that as a field in Form2. Then, when you want to change the label use the instance that was passed in. I'm answering from my phone so when I get to my desk I can elaborate with code.
But what's happening here is that you're creating a new Form1 and setting the value.
private Form1 _form1;
...
public Form2(Form1 form1)
{
_form1 = form1;
}
...
private void changeForm1_Click(object sender, EventArgs e)
{
StaticVariables.labelString = textBox.Text;
_form1.ChangeLabel();
}
and then finally, when you launch Form2:
var form2 = new Form2(this);
form2.Show();
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 );
}
}