How to access one object from another form in C#? - c#

Let's say I have "Form1" and "Form2", both are forms.
In Form1 there are the Main Class and the Main method.
In Form1 I create an object like:
public myobject ob1 = new myobject();
But then, in Form2, I have this code:
private void bdCancelar_Click(object sender, EventArgs e)
{
ob1.status = 1; // I can't access ob1 !!!
}
Any help ?
Thanks.

You need an instance of Form1. Normally if you have displayed this form you have instantiated it (Form1 form1 = new Form1()). Then you could operate on this instance and access public members:
form1.ob1.status = 1;
Another possibility is to have your Form2 constructor take a Form1 instance:
public class Form2: Form
{
private readonly Form1 _form1;
public Form2(Form1 form1)
{
_form1 = form1;
}
private void bdCancelar_Click(object sender, EventArgs e)
{
_form1.ob1.status = 1;
}
}
and then when you are somewhere inside Form1 and want to create and show Form2:
var form2 = new Form2(this);
form2.ShowDialog();

Related

How To access winforms parent Form controls from a child Form

In Form1 I have one DataGridView and multiple textboxes. When I click A button in Form2 I need to save the data from DataGridView and multiple textboxes to Database. How to Implement in C sharp Windows Application
Form1 Button Click event. I opened Form2
public sealed partial class form1 : Form
{
private static form1 instance = null;
public static form1 Instance
{
get
{
if (instance == null)
{
instance = new form1();
}
return instance;
}
}
private void button1_Click(object sender, EventArgs e)
{
textbox2.Text=100;
form2 CO = new form2();
CO.Show();
}
}
I want to attach textboxes data and Datagridview content to
object SO and Call InsertSale function .textboxes and datagridview are in form1
This is Button Click Event in Form 2
private void button1_Click(object sender, EventArgs e)
{
clsSale SO = new clsSale();
SO.Totamount = Convert.ToDecimal(form1.Instance.textBox2.Text);
SO.InserSale(SO);
}
If Form2 wants to access the Form1 properties.
Pass ParentForm instance to the ChildForm constructor. Add a public method in the parent form to update its properties from child form.
public partial class Form1: Form
{
public Form1()
{
InitializeComponent();
}
public void SetTextBoxValue(string val)
{
this.textBox1.Text = val;
}
private void CreateForm2()
{
var form2 = new Form2(this);
form2.Show();
}
}
public partial class Form2: Form
{
private Form1 form1;
public Form2(Form1 frm1)
{
InitializeComponent();
form1= frm1;
form1.SetTextBoxValue("Value from Form2");
}
}
Create a global class, such as Global.cs, in the project. Then declare the following variables:
public static Form1 frm1
public static Form2 frm2
Declare a variable of the Form class - Form frm1 or Form frm2 etc.
Now access the variables from any form as follows:
Global.frm1 = new Form1() // - for the Home Form1
Global.frm1.ShowDialog();
Global.frm2 = new Form2() // - for the Home Form1
Global.frm2.ShowDialog();
If you want to access a control in any form, just extend them as follows:
frm1.txtBox1.Text
frm2.button1.Click() // etc.

How to reLoad a form from another form

I have two forms, Form1 and Form2. I use ShowDialog() on Form2 from Form1. How can I run Form1Load() from Form2? Specifically, I want to refresh Form1 from Form2.
Firstly, make sure you assigning the Owner property on Form2 before showing it. This allows you to access the current instance of Form1.
class Form1 : Form
{
public void Method()
{
var form2 = new Form2();
form2.Owner = this;
form2.ShowDialog();
}
}
From Form2 you can this use this.Owner to access the instance of Form1 and call any public methods or access any public properties. (Make sure the load event handler is public)
class Form2 : Form
{
public void Method()
{
this.Owner.form1_Load(null,null); //assuming you don't use these params.
}
}
In your form1_Load() I would recommend putting in a this.Refresh() to "refresh" the form. The refresh doesn't update some things that have data stored, it only repaints the form, so in the load event you will have to manually "refresh" things.
Create an instance of Form1 and then use the Refresh method or your Form1_Load method with that instance.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void ShowMessage(string message)
{
MessageLabel.Text = message;
}
private void ShowForm2(object sender, EventArgs e)
{
Form2 Form2Copy = new Form2(this);
Form2Copy.ShowDialog();
}
}
and
public partial class Form2 : Form
{
Form1 Form1Copy;
public Form2(Form1 Parent)
{
InitializeComponent();
Form1Copy = Parent;
}
public void Button_Click(Object sender, EventArgs e)
{
Form1Copy.ShowMessage("Hello from Form2!");
}
}
Pass in Form1 to the ShowDialog() method of your Form2 instance:
private void Form1_Load(object sender, EventArgs e)
{
this.LoadEventCode();
}
public void LoadEventCode()
{
this.Text = DateTime.Now.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.ShowDialog(this); // <-- pass in Form1
}
Now over in Form2, cast the .Owner property to Form1 and do what you need:
private void button1_Click(object sender, EventArgs e)
{
Form1 f1 = (Form1)this.Owner;
f1.LoadEventCode();
}

Parent's name of Form.show()

I use Form.Show() to open a new form
Like this:
public Form2()
{
Form1 fm = new Form1();
fm.Show();
}
How do I get Form2's name when Form1 has control?
What I am doing is create a public variable(ex.pFormname) in From1
and set pFormname = Form2 before the show common like this:
public Form2()
{
Form1.pFormname = "Form2";
Form1 fm = new Form1();
fm.Show();
}
Is there any other way except creating a public variable?
And is there any resource release should I do after closing Form1?
public Form2()
{
Form1 fm = new Form1();
Form1.pFormname = this.Text; // this = Form2, Text = the arbitrary name of the form.
fm.Show();
}
This requires you to have a public instance variable or property called pFormname in Form1 class. the 'this' keyword represents the current instance of Form2, and Text is the property which contains the name of the Form.
If you want to access other properties on the parent form, you could pass it as a reference when you instantiate Form1.
public Form2()
{
Form1 fm = new Form1(this); // this = form2.
fm.Show();
}
In Form1 you would have something like this:
public partial class Form1 : Form
{
private Form2 _parentForm;
public Form1(Form2 parentForm)
{
_parentForm = parentForm;
InitializeComponent();
}
}
And you would call public variables/properties/methods like this:
_parentForm.SomeMethod();
You could use the forms Owner property and pick that up in your instance later. For example in the constructor of Form2:
public Form2()
{
Form1 fm = new Form1 {Owner=this};
fm.Show();
}
You use the Owner name in Form1 like this
public class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Load += Form1_Load;
}
void Form1_Load(object sender, EventArgs e)
{
label1.Text += Owner.Name;
}
}
If you want to find the name of the parent form , you can do so by using
string s = ParentForm.Name; // s will contain the name of the parent form
Hope this helps..
If you want to find out , the child ..you can do so by:
MdiChildren property.
this will help you to find out , which child forms(Form 2) are contained by currently opened form(Form1).
Refer to this for how to use this exactly:
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.mdichildren(v=vs.110).aspx
The best thing you can do in that situation is to have a private field in Form1 and set it equal to Form2 when you instantiate it like this.
class Form1 : Form
{
private Form _parentForm;
public Form1(Form f)
{
_parentForm = f;
}
}
and when you instantiate Form1 do like this
Form1 fm = new Form1(this) // in the constructor of Form2;
after this you will have the reference to the Form2 in the Form1's _parentForm variable and you can easuily access any of its properties for instance;
MessageBox.Show(_parentForm.Name) // in Form1 will show the name of Form2
or you can just have a string which you set the this.Name when you instantiate Form1 in Form2's constructor
class Form1 : Form
{
private string _parentFormName;
public Form1(string name)
{
_parentForm = f;
}
}
Form1 fm = new Form1(this.Name) // in the constructor of Form2;
and then you can directly call that variable like this
MessageBox.Show(_parentFormName);

Returning data to Forms without opening a new instance

I am trying to return some data from Form2 to Form1, everything seems fine, I got the data and so, but, when I try to pass my data to a textbox, it doesn't changes the text. Only if I open a new instance of Form1, on Form2 it works. Why this happen? Can't I send the text to the old instance?
I'm using this code;
Form1 (Main Form)
public void updateText(string data)
{
MessageBox.Show(data);
txtGood.Text = data;
}
Form2 SecondaryForm = new Form2();
SecondaryForm.ShowDialog();
Form2 (Second Form with user data)
Form1 MainForm = new Form1();
MainForm.updateText(data);
MainForm.ShowDialog();
this.Close();
So, my question is, how can I pass the data values to the old instance of the main form? without having to create a new instance and show a new instance. Is there a way to do this?
This is because you're creating a instance of Form1 in your Form2 code. What you want to do is setup Form2's parentForm to be the instance of the Form1 that created it.
public partial class Form1 : Form
{
public void CreateForm2()
{
Form2 form2 = new Form2(this);
form2.ShowDialog();
}
public string MyTextboxText
{
get { return txtMyTextbox.Text; }
set { txtMyTextbox.Text = value; }
}
}
public partial class Form2 : Form
{
private Form1 parentForm;
public Form2(Form1 parentForm)
{
this.parentForm = parentForm;
}
public void myButtonClick()
{
parentForm.MyTextboxText = "Hello";
}
}
This code is just an example, probably wont compile as-is.
What you can do is pass the reference of MainForm(Form1) to second Form(Form2). Then instead of creating MainForm again use the reference to update the textbox.
//pass reference to form2
Form2 SecondaryForm = new Form2(mainForm);
SecondaryForm.ShowDialog();
//in the constructor of Form2 save the reference of Form1
Form1 form1 = null
Form2(Form1 mainForm)
{
form1 = mainForm;
}
//then instead of creating a new MainForm again just use reference of Form1
form1.updateText(data);
this.Close()
main form:
private void Button2_Click(object sender, EventArgs e) {
frmCustomersRecord rec = new frmCustomersRecord(this);
rec.ShowDialog();
rec.GetData();
}
child form:
public partial class frmCustomersRecord : Form
{
public frmCustomersRecord()
{
//blank contructor (Instance of an class)
}
frmCustomerDetails cd;
public frmCustomersRecord(frmCustomerDetails parentForm) : this()
{
this.cd = parentForm;
}
//call the methods using child form object
}

Access Of Public Method Between Forms

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.

Categories

Resources