How to Access a Form Control for Another Form

How to access a form control for another form?

Making them Singleton is not a completely bad idea, but personally I would not prefer to do it that way. I'd rather pass the reference of one to another form. Here's an example.

Form1 triggers Form2 to open. Form2 has overloaded constructor which takes calling form as argument and provides its reference to Form2 members. This solves the communication problem. For example I've exposed Label Property as public in Form1 which is modified in Form2.

With this approach you can do communication in different ways.

Download Link for Sample Project

//Your Form1

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2(this);
frm.Show();
}

public string LabelText
{
get { return Lbl.Text; }
set { Lbl.Text = value; }
}
}

//Your Form2

public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}

private Form1 mainForm = null;
public Form2(Form callingForm)
{
mainForm = callingForm as Form1;
InitializeComponent();
}

private void Form2_Load(object sender, EventArgs e)
{

}

private void button1_Click(object sender, EventArgs e)
{
this.mainForm.LabelText = txtMessage.Text;
}
}

alt text

(source: ruchitsurati.net)

alt text

(source: ruchitsurati.net)

Fully access a control from another Form

You can access the the owner form in the child using:

((Form1)Owner).textBox1.Text = "blah";

Assuming you have called your the child form using:

Form2 form = new Form2();
form.Show(this);

Accessing button from another form

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);
}

Interaction between forms — How to change a control of a form from another form?

Form in Windows Forms is a class like other C# classes. The way of communicating between forms are the same as classes. You can consider this options when communicating between classes:

Manipulate second Form from first Form

  • You can add suitable parameters to the constructor of the second form. Then you can pass values to the constructor when creating an instance of the second form. In the second form store parameters in member fields and use them when you nees.

  • You can create public property or method in the second form and set those properties after creating an instance of the second form. This way you can use them when you need in the second form. This option is not limited to passing values when creating the second form. You can even use that property during the execution of second Form. Also it's useful for getting a value from it.

  • As another option you can make the control which you want to manipulate it public and this way you can access to it from other form. Using a method is a more recommended way of doing this.

Manipulate first Form from second form

  • You can create a public method or property in first form and pass an instance of the first form to second form. Then using that method/property on the passed instance, you can manipulate the first form.

  • You can create an event in second form and after creating an instance of second form subscribe for it in first form and put the code for changing the form in the handler. Then it's enough to raise the event in second form.

  • You can define a public property of type Action or some other delegate type in second form and then after creating an instance of second form, assign the property using a custom action. Then in second form, it's enough to invoke the action when you need to manipulate first form.

  • Also here you can make a control of first form to be public and then if you pass an instance of the first form to the second form, you can manipulate the control. It's recommended to use other solutions. It's like creating public property or method, but a method which performs specific task on the control is better that exposing the whole control. But you may need this solution some times.

Here are some useful examples about above solutions.

Manipulate second Form from first Form

Example1 - Using constructor of second Form

Use this example when you need to pass some data to second form, when creating the second form.

public partial class Form2 : Form
{
int selectedValue;
public Form2(int value)
{
InitializeComponent();
selectedValue = value;
}
private void Form2_Load(object sender, EventArgs e)
{
//Load data
this.comboBox1.DataSource = new MyDbContext().Categories.ToList();
this.comboBox1.DisplayMember = "Name";
this.comboBox1.ValueMember = "Id";
this.comboBox1.SelectedValue = selectedValue;
}
}

Then in your first form, it's enough to pass the value to Form2 when you create a new instance of it:

var value = 2; // Or get it from grid
var f = new Form2(value);
f.ShowDialog();

Example2 - using public Property or Method of second Form

Use this example when you need to pass some data to second form, when creating or even after creation of second form.

public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public string SomeValue
{
get { return textBox1.Text;}
set { textBox1.Text = value;}
}
}

Then in your first form, it's enough to pass the value to Form2 when you need, after creating Form2 or whenever you need to set value of textBox1 on Form2:

var f = new Form2(); //value is not needed here
f.SomeValue = "some value";
f.Show();
//...
f.SomeValue = "some other value";

Example 3 - Making a Control of Second form public

Use this example when you need to change a property of a control on second form, when creating or even after creation of second form. It's better to use public property or method instead of exposing whole control properties.

In your Form, at designer, select the control and in Properties window set the Modifiers property to Public. Also make sure the GenerateMember property is true. Then you can simply access this control using its name from outside of the Form.

var f = new Form2();
f.textBox1= "some value";
Manipulate first Form from second form

Example 4 - Create public Method or Property in first Form and pass an instance of First Form to constructor of second Form

Use this example when you need to change first Form from second Form.

In your Form1, create a property of a method that accepts some parameters and put the logic in it:

public void ChangeTextBox1Text(string text)
{
this.textBox1.Text = text;
}

Then create a constructor in Form2 which accepts a parameter of type Form1 and keep the passed value in a member field and use it when you need:

Form1 form1;
public Form2 (Form1 f)
{
InitializeComponent();
form1 = f;
}
private void button1_Click(object sender, EventArgs e)
{
form1.ChangeTextBox1Text("Some Value");
}

Now when creating Form2 you should pass an instance of Form1 to it:

var f = new Form2(this);
f.Show();

Example 5 - Using event of second Form in first Form

Take a look at this post. It's about communication between form and a control, but it's applicable to communication between forms also.

Example 6 - Injection an Action in second Form

Take a look at this post. It's about communication between form and a control, but it's applicable to communication between forms also.

Example 7 - Making a Control of first form public

In this solution you need to make a control in first form public, like example 3. Then like example 4 pass an instance of the first form to second form and keep it in a field and use it when you need. Using a public method or property is preferred.

Form1 form1;
public Form2 (Form1 f)
{
InitializeComponent();
form1 = f;
}
private void button1_Click(object sender, EventArgs e)
{
form1.textBox1.Text = "Some Value";
}

when creating Form2 you should pass an instance of Form1 to it:

var f = new Form2(this);
f.Show();

could i accessing a form control in another user control without making a new instance?

Abanoub - If I understand what you are trying to do - you want to set the label of an already displayed form without creating a new instance of the form. At least one way to do that would be with a singleton class that holds the form instance. So there will only be one instance of the form. Please try the following:

First, we create a singleton class that keeps the form instance:

public class Singleton
{
// Modified from: http://csharpindepth.com/articles/general/singleton.aspx

// This will keep ONE instance of the Admin Form
private Admin _adminForm;
public Admin AdminForm
{
get
{
if (_adminForm == null)
{
_adminForm = new Admin();
}
return _adminForm;
}
}
private static Singleton instance = null;

public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}

Now you instantiate the from from this instance - for example:

Button 1 will display the form:

    private void button1_Click(object sender, EventArgs e)
{
var singleton = Singleton.Instance;
var f = singleton.AdminForm;
f.Show();
}

Button 2 will set the already displayed form's label (BTW - I think you want the property to set the text of the label not the label right?)

    private void button2_Click(object sender, EventArgs e)
{
// Assuming you clicked button 1 first,
// this will not cause a new instance but use the existing one
var singleton = Singleton.Instance;
var f = singleton.AdminForm;
f.LabelText = "Hello world!";
}

Assuming you want to set the text of the label - here is the modified property in Admin:

    public string LabelText
{
get { return label8.Text; }
set { label8.Text = value; }
}

I hope this will be helpful to you - good luck!!

I need to access a form control from another class (C#)

Maybe a bit late, but by all means, here is another approach, that's still more clean than David's approach:

You should add an EventHandler in your MyNewClass. Then you can subscribe to that event from within your form.

public partial class Form1 : Form
{
private readonly MyNewClass _myNewClass;

public Form1()
{
InitializeComponent();
_myNewClass = new MyNewClass();
_myNewClass.DisplayPanelsInvoked += DisplayPanelsInvoked;
}

private void DisplayPanelsInvoked(object sender, DisplayPanelsEventArgs e)
{
var panels = e.Panels; // Add the panels somewhere on the UI ;)
}
}

internal class MyNewClass
{
private IList<Panel> _panels = new List<Panel>();

public void AddPanel(Panel panel)
{
_panels.Add(panel);
}

public void DisplayPanels()
{
OnDisplayPanels(new DisplayPanelsEventArgs(_panels));
}

protected virtual void OnDisplayPanels(DisplayPanelsEventArgs e)
{
EventHandler<DisplayPanelsEventArgs> handler = DisplayPanelsInvoked;
if (handler != null)
{
handler(this, e);
}
}

public event EventHandler<DisplayPanelsEventArgs> DisplayPanelsInvoked;
}

internal class DisplayPanelsEventArgs : EventArgs
{
public DisplayPanelsEventArgs(IList<Panel> panels)
{
Panels = panels;
}

public IList<Panel> Panels { get; private set; }
}

In my opinion it's a better solution, because you don't need to provide a reference of the form to the MyNewClass instance. So this approach reduces coupling, because only the form has a dependency to the MyNewClass.

If you always want to "update" the form whenever a panel is added, you could remove the DisplayPanels-method and shorten the code to this:

public partial class Form1 : Form
{
private readonly MyNewClass _myNewClass;

public Form1()
{
InitializeComponent();
_myNewClass = new MyNewClass();
_myNewClass.PanelAdded += PanelAdded;
}

private void PanelAdded(object sender, DisplayPanelsEventArgs e)
{
var panels = e.AllPanels; // Add the panels somewhere on the UI ;)
}
}

internal class MyNewClass
{
private IList<Panel> _panels = new List<Panel>();

public void AddPanel(Panel panel)
{
_panels.Add(panel);
OnPanelAdded(new DisplayPanelsEventArgs(_panels, panel)); // raise event, everytime a panel is added
}

protected virtual void OnPanelAdded(DisplayPanelsEventArgs e)
{
EventHandler<DisplayPanelsEventArgs> handler = PanelAdded;
if (handler != null)
{
handler(this, e);
}
}

public event EventHandler<DisplayPanelsEventArgs> PanelAdded;
}

internal class DisplayPanelsEventArgs : EventArgs
{
public DisplayPanelsEventArgs(IList<Panel> allPanels, Panel panelAddedLast)
{
AllPanels = allPanels;
PanelAddedLast = panelAddedLast;
}

public IList<Panel> AllPanels { get; private set; }
public Panel PanelAddedLast { get; private set; }
}

Accessing Form's Controls from another class

EDIT: Lot of edit.

public partial class Form1 : Form
{
// Static form. Null if no form created yet.
private static Form1 form = null;

private delegate void EnableDelegate(bool enable);

public Form1()
{
InitializeComponent();
form = this;
}

// Static method, call the non-static version if the form exist.
public static void EnableStaticTextBox(bool enable)
{
if (form != null)
form.EnableTextBox(enable);
}

private void EnableTextBox(bool enable)
{
// If this returns true, it means it was called from an external thread.
if (InvokeRequired)
{
// Create a delegate of this method and let the form run it.
this.Invoke(new EnableDelegate(EnableTextBox), new object[] { enable });
return; // Important
}

// Set textBox
textBox1.Enabled = enable;
}
}

Accessing a controls value from another form

First of all set the Label lblDraw as

In frmStats form

 public string strNumber
{
get
{
return lblDraw.Text;
}
set
{
lblDraw.Text = value;
}
}

Form1

    if (winner != 0)
this.Text = String.Format("Player {0} Wins!", winner);
else if (winner == 0 && turnCounter == 9)
{
this.Text = "Draw!";
//this is where i want/think the code should be to change the label
frmStats frm = new frmStats();
string number = frm.strNumber;
frm.strNumber = (Convert.ToInt32(number) + 1).ToString(); //incrementing by 1
}

or else simply set the Label lblDraw modifier as public, which is not recommended.

Accessing a Tab Control From Second Form And Inserting The Form Into First Form Tab Control

Have you tried:

tabpage.Controls.Add(pd)

Update:

program.cs

public static Form1 from;  //<--- important
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
using (Form1 mainForm = new Form1())
{
from = mainForm;

Application.Run(from);
}
}

3rd form window or whatever:

private void button1_Click(object sender, EventArgs e)
{

Form2 f2 = new Form2();

TabPage tabpage = new TabPage();
tabpage.Text = f2.Text;
Program.from.tabControl1.TabPages.Add(tabpage);
f2.TopLevel = false;
f2.Parent = tabpage;
f2.Dock = DockStyle.Fill;
Program.from.tabControl1.SelectedTab = tabpage;
f2.Show();
}

That should help you manipulate things for the main form.



Related Topics



Leave a reply



Submit