This question has been asked many times and I have provided some ways of doing this but the methods for doing so always relied on either setting the modifiers of each and every control to public or declaring public methods like:
internal TextBox GetTextBox()
{
return TextBox1;
}
While this method works, it means that you need to have a method for ALL the controls on a form that you want to have access to.
This is ok if you have one or two, but what if you have 10, 20 or more!
A solution to this problem is to have a worker class in your project that will access the controls on any form without public methods or accessor variables e.g..
public partial class Form1 : Form
{
internal Form2 form2;
internal TextBox te;
public Form1()
{
InitializeComponent();
form2 = new Form2();
form2.Show();
Te = TextBox1;
}
}
Using a worker class, you can do away with declaring methods and accessor variables to modify properties and fire events from any other form in your project.
So, how is this done?
If your project contains two or more forms, create a class called FindControl; in this declare a member variable of FormCollection:
FormCollection fc = Application.OpenForms;
And two more:
Control c = null;
Control f = null;
This will be used to retrieve forms by their Name property in a public method eg.
Next, declare a method, here we find and return the form object as a Control:
public Control TheForm(string name)
{
for (int i = 0; i < fc.Count; i++)
{
c = null;
if (fc[i].Name == name)
{
f = fc[i];
break;
}
}
return ((Control)f);
}
A Form is a Control so we can cast any form in your project as a simple Control object.
Example;
Control c = TheForm("Form1");
Once we have this, we can gain access to ALL the child controls including the children in other container controls on the form.
The next method to declare is the one that locates the control to access on the form returned by the TheForm method.
public Control Ctrl(Control f, string name)
{
for (int i = 0; i < f.Controls.Count; i++)
{
//look for the control by name
if (f.Controls[i].Name == name)
{
c = f.Controls[i];
break;
}
//control may be on a container control on the form, look for it there.
if (c == null)
{
if (f.Controls[i].Controls.Count > 0)
Ctrl(f.Controls[i], name);
}
//found the control, get out of here
if (c != null)
break;
}
return (c);
}
What next? NOTHING; this is all that is needed to access any control's properties from any form including a GridViews Rows, columns Cells, TrieeViews nodes etc…
Ok, we have our class, how do we use it?
Simple,
on each form that you want to access controls of other forms, declare a FindControl object:
FindControl fc = new FindControl();
Now if you want to access the Text property on a TextBox control of another form you simply call:
FindControl.Ctrl("The Form where the control is on", "the name of the control")
Real world examples;
((TextBox)fc.Ctrl(fc.TheForm("Form1"), "te")).Text = "Hello World - Form 1";
((TextBox)fc.Ctrl(fc.TheForm("Form2"), "te")).Text = "Hello World - Form 2";
((TextBox)fc.Ctrl(fc.TheForm("Form2"), "e")).Text = "Hello World - Panel";
DataGridView dgv = ((DataGridView)fc.Ctrl(fc.TheForm("Form2"), "dg"));
dgv.Rows[0].Cells[0].Value = "Hello World";
((DataGridView)fc.Ctrl(fc.TheForm("Form2"), "dg")).Rows[0].Cells[0].Value = "Grid View Column 1 - Hello World";
((DataGridView)fc.Ctrl(fc.TheForm("Form2"), "dg")).Rows[0].Cells[1].Value = "Grid View Column 2- Hello World";
I have not tested all controls but I have tested the above examples; these work and I have no doubt that this will work with all controls on any form.
The beauty of this class is that it is written once and by casting to the control type, you only need to declare one object FindControl to, alter text, fill list boxes, add nodes to tree views, add rows and columns to grid views, press buttons or fire events of those controls on other forms.
How easy is this?
There is no special coding, just the stock standard methods you are familiar with.