form A opens form B, and form A.visible = false;
form A has a public int variable and I need controls in form B to be able to access and modify this variable. could this be done as passing the value through the constructor is only one way!
and so if it could be done, if form A is not visible could the value still be accessed?
(form b is not supposed to be dialog!)
many thanks!
edited: I do not quite get the explanations actually. so far it is like that:
in form a:
//in global space
public int temp = 123;
//in form_load event
Form setup = new setup();
setup.Show();
this.Visible = false;
in form setup:
//in form_load event
textBox1.text = temp.toString();
//in button_press event
form a.temp = "456";
I hope I have explained my stance clearly!
First, have member field in form B of type form A:
private FormA parent;
Second, have such constructor in form B:
public FormB(FormA parent)
: this()
{
this.parent = parent;
}
Now when you create instance of form B, pass reference to the running form A instance:
FormB formB = new FormB(this);
formB.Show();
And you can access the public property through the parent field e.g.
//inside Form B code..
public Foo()
{
parent.PUblicProp = "Hello";
}
this is one way to pass values from one form to another form
public partial class Form2 : Form
{
public string MyProperty { get; set; }
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
label1.Text = MyProperty;
}
}
after that in the button click event handler in Form1
add the following code
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.MyProperty = "This is from Form1";
form2.Show();
}
}
Since your int variable is public then your controls in formB can access and modify it, formA visibility won't affect this it will be accessed disregarding the visibility of it:
FormA f = new FormA();
int newValue = f.yourintvariable;
And there are a lot of alternative ways like using constructor to send the variable in the FormA constructor and initialize it from FormB,
or you can define it as static but in this case will be one variable for all the instances of thid form
Related
I have a WinForms application. In the main form, I coded a method that will clear all TextBoxes in whatever form is passed as a parameter. I want to call this method from another form. The following code is what I came up with after much trial/error and browsing this site. Is instantiating a new version of the main form every time the new form's clear all button is clicked good practice? If I were to make yet another form with it's own clear all button I would have to instantiate a new main form by similar practice (unless I made the method static)? Can anyone suggest alternative ways of accessing one form's method from a different form? Many thanks in advance.
Edit: I know making the method static would be a simple and effective solution, but I'm curious about using a non-static way.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void ClearAll(Form formToClear) //CLEAR TEXTBOXES
{
foreach (var box in formToClear.Controls.OfType<TextBox>())
{
box.Text = "";
}
}
}
public partial class NewItemForm : Form
{
public NewItemForm()
{
InitializeComponent();
}
private void clearAllButton_Click(object sender, EventArgs e)
{
Form1 mainForm=new Form1();
mainForm.ClearAll(this);
}
}
You don't have to make your ClearAll method static. It is enough if you keep a global reference to your main form. You can do it in Program.cs. This is not the best way though.
static class Program {
public static Form1 TheForm;
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
TheForm = new Form1();
Application.Run(TheForm);
}
}
Again! Just because it can be done, it does not mean that I would encourage you doing it. This is not in the spirit of OOP.
If the only reason you would like to access a Form1's method is to clear TextBoxes, then I would recommend creating an intermediate class:
public class InterForm : Form
{
public void ClearAll() //CLEAR TEXTBOXES
{
foreach (var box in this.Controls.OfType<TextBox>())
{
box.Text = "";
}
}
}
All other form should inherit from InterForm.
You should almost certainly create a static utility class with static functions. That will preserve memory by preventing unnecessary Form1 instances from being created. Depending on the size of your Form class and the objects/variables contained within, creating a new instance just to use 1 function from that class, could eventually result in a large amount of memory being lost over time. A static method in a static class would prevent that from happening because static methods are only defined/instantiated once in the lifetime of the process, versus once-per-instance.
You should probably go with something like:
internal static class FormUtils
{
internal static void ClearAllTextBoxes(Form form)
{
if (form == null)
return;
if (form.Controls.Count <= 0)
return;
foreach (var box in form.Controls.OfType<TextBox>())
{
box.Clear();
}
}
}
Then, that function would be used like this:
public partial class NewItemForm : Form
{
public NewItemForm()
{
InitializeComponent();
}
private void clearAllButton_Click(object sender, EventArgs e)
{
FormUtils.ClearAllTextBoxes(this);
}
}
You can use concept of Event here.
Your Another form form where you want to call method of your main form should be having a Event,
while creating an instance of this form (I guess you are creating an instance of this form from main form only) you can subscribe an event of this form to your targeted method.
So whenever you are required to call that method of your main form (from your another form), you can raise that event.
see below sample code.
Suppose Form1 is your main form
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
void f2_ClearTextBoxOfForm(Form targetForm)
{
foreach (Control control in targetForm.Controls)
{
if (control is TextBox)
((TextBox)control).Text = string.Empty;
}
}
private void btnShowForm2_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.ClearTextBoxOfForm += f2_ClearTextBoxOfForm;
f2.Show();
}
}
and Form2 is your another form from which you want to clear all textboxes of Form1
public delegate void ClearTextBoxEventHandler (Form targetForm);
public partial class Form2 : Form
{
public event ClearTextBoxEventHandler ClearTextBoxOfForm;
public Form2()
{
InitializeComponent();
}
private void btnClearTextBox_Click(object sender, EventArgs e)
{
if (ClearTextBoxOfForm != null)
{
//here passing 'this' means we want to clear textBoxes of this form (Form2)
//you can pass any Form's object of which you want to clear Textboxes
ClearTextBoxOfForm(this);
}
}
}
This question already has answers here:
Pass variable between forms when clicking button
(5 answers)
Closed 8 years ago.
I'd like to know how to pass, let's say an integer, from form1 to form2.
I tried to do that through a button that would open form2, but the event button click didn't recognize the integer... What should I do?
In form1 I have integer x, and I want that when I click on button1, form2 would open up with x value in a label.
If there's a way to pass the info without the button (then I could use the button just to open form2) that would be great as well.
you can use second form constructor.
private int input;
public Form2(int input)
{
this.input = input;
InitializeComponent();
}
when you create an object , you can pass your var(int in here):
int myvar=911;
Form2 tmp = new Form2(myvar);
tmp.Show();
now you can use that private variable in form2:
lbl.Text=input.toString();
in Form1:
private void button1_Click(object sender, EventArgs e)
{
Form2 tmp = new Form2(911);
tmp.Show();
}
and in Form2:
public Form2(int input)
{
InitializeComponent();
label1.Text = input.ToString();
}
send your code for solve this problem.i can't find out why it doesn't recognize your vars without your codes!
In your code have a variable accessible by both forms. For example create a new Namespace and add a public static class FormData with a public static int Value inside.
namespace GlobalVariables
{
public static class FormData
{
public static int Value { get; set; }
}
}
Then from both of your forms you can access the said variable (and modify it) with GlobalVariables.FormData.Value. Here I made it a property, but you can do pretty much whatever you want with it.
Alternatively to passing the value by Form2 constructor, you can create a property that sets the label value, e.g.
Form2
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public int XValue{
set{
label1.Text = value.ToString();
}
}
}
Form1
public partial class Form1 : Form
{
private int x = 10;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.XValue = x;
form2.Show();
}
}
I want to access a method in a child form from parent form.I have used the following code to access the controls.
Form form = (Form)Application.OpenForms["frmname"];
if (tableform != null)
{
GroupBox grp = (GroupBox)tableform.Controls["grpbxname"];
Panel table = (Panel)grp.Controls["panelname"];
}
Using the following code I am able to access controls in the child form from the parent form.
Same way I want to access the function/method in the child form.
For ex: from.newmethod();
Is there any possibility to achieve this,without creating new instance of form.It windows application using c#.net
Thanks.
declaring a method public is not a good practice. you can create delegate or event instead. you can create public delegate for that method and execute that delegate from the outside the class Or you can create Event that you can handle from the outside of the class.
public partial class Form1 : Form
{
public delegate void dMyFunction(string param);
public dMyFunction delMyFunction;
public Form1()
{
InitializeComponent();
delMyFunction = new dMyFunction(this.MyFunction);
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.Show();
}
private void MyFunction(string param)
{
this.Text = param;
}
}
Now, you can call this delegate from the outside the class
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
Form1 frm = (Form1)Application.OpenForms["Form1"];
frm.delMyFunction.Invoke("Hello");
//On Form load this method will be invoked and Form1 title will be changed.
}
}
I am working on a game that utilizes Windows Forms in C#. I want to be able to use the first form to call a second form. I have this working. Then I would like for the second form to send data back to the first form rather than creating a new instance of the first form. Can this be done? I know I need to have my properties set up so that I can set the variables from one form to the other. I am just not sure how to go about calling the first form without creating a new instance of it.
Is there a way that this can be done?
For example if I have Form A create an instance of Form B, can I have Form B do some work and send the data back to the original Form A without creating a new instance of Form A?
If you don't use the Data sent back Form A right away then you could use the Form_Closing event handler Form B and then a public property in Form B also.
In your Form A it could look like this:
public partial class FormA : Form
{
FormB frmB = new FormB(); // Instantiate FormB so that you could create an event handler in the constructor
public FormA()
{
InitializeComponent();
// Event Handler for Form Closing
frmB.FormClosing += new FormClosingEventHandler(frmB_FormClosing);
}
void frmB_FormClosing(object sender, FormClosingEventArgs e)
{
String fromFormB = frm2.FormBData; // Get Data from Form B when form is about to close
}
private void button1_Click(object sender, EventArgs e)
{
frmB.ShowDialog(); // Showing Form B
}
}
And in your Form B it could look like this:
private void button1_Click(object sender, EventArgs e)
{
// Let just say that the data is sent back once you click a button
FormBData = "Hello World!";
Close();
}
public String FormBData { get; set; }
It's hard to say without knowing your full requirements. But generally I go like this (Somewhat psuedo code).
Form2 dialogForm = new Form2();
if(dialogForm.ShowDialog() == DialogResult.OK)
{
this.PropertyOnForm1 = dialogForm.PropertyOnForm2
}
This ofcourse relies that your second form is a dialog. You will need to set the dialogresult buttons on Form2, and have a public property that will be accessed from Form1 once the dialog has been completed.
Let me know if this doesn't work and I'll write up a different answer.
Since you are creating Form2 in Form1, you can create a custom event in Form2 and subscribe to it in Form1 at the time that you create Form2, if you are returning information from Form2 when you are closing it then Edper's or MindingData's answers will work.
Here is a quick and dirty example using EventHandler<TEventArgs>
Form1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.myCustomEvent += frm2_myCustomEvent;
frm2.Show();
}
void frm2_myCustomEvent(object sender, string e)
{
this.Text = e;
}
}
Form2
public partial class Form2 : Form
{
public event EventHandler<string> myCustomEvent;
int count;
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
count +=1;
myCustomEvent(sender, count.ToString());
}
}
I have 2 Forms. Form1 creates Form2 like this:
public partial class Form1 : Form
{
private void button3_Click(object sender, EventArgs e)
{
Form2 AcqForm = new Form2();
AcqForm.Show();
string[] ret = AcqForm.fulldate;
MessageBox.Show(ret[27]);
}
}
public partial class Form2 : Form
{
public string[] fulldate; //Created in form 2
close(); //Need to get this string back on or before close event
}
How should I go about doing this?
You need to handle the Form2 instance's FormClosed event in the first form and access the public properties.
Using this snippet, you can get a little knowledge on it.
in Form1:
using(Form2 form2 = new Form2())
{
if(form2.ShowDialog() == DialogResult.OK)
{
MessagBox.Show(form2.fulldate);
}
}
In Form2:
public partial class Form2 : Form
{
public string[] fulldate {get; set;} // Create a Property
void CloseForm()
{
fulldate = "valueToReturn";
DialogResult = DialogResult.OK;
}
}
Assuming you want button3_Click to wait until AcqForm is closed before accessing fulldate, you'll first have to change AcqForm.Show(); to AcqForm. ShowDialog();. (Show() doesn't wait for it to close.)
As for the fulldate field – it will be accessible even after the form closes because the form still exist. SLaks' remark about it being a 'field' means that we have different names for different types of 'variables'. What you have declared in the class (without get and set) is called a field. A variable in a method is called a 'variable'.
If you still want to do something when AcqForm closes, do this:
In Form1's constructor, before the AcqForm. ShowDialog();:
AcqForm.FormClosing += AcqForm_FormClosing;
And in Form1's class:
void AcqForm_FormClosing(object sender, FormClosingEventArgs e)
{
//Whatever will be here will be done when the form is closing.
//Use 'FormClosed' for doing things AFTER the form has closed.
}