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;
}
}
(source: ruchitsurati.net)
(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 FormExample1 - 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 formExample 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
C# String to Hex , Hex to Byte Conversion
How to Map to a Dictionary Object from Database Results Using Dapper Dot Net
How to Refresh or Show Immediately in Datagridview After Inserting
Fetching Value from a Datatable into Datatable With Where Clause
How to Provide Success Messages ASP.NET MVC
Use Linq to Collaps Multiply Collections into One Collection
Replace Single Backslash With Double Backslash
How to Get an Specific Header Value from the Httpresponsemessage
Repaired Records:Cell Information from Worksheet Created from Scratch
How to Change a Image on a Button Using Windows Forms
Get File Name from Byte Array or Stream
Decrypt M3U8 Playlist Encrypted With Aes-128 Without Iv
How to Ignore the Certificate Check When Ssl
Epplus: Find If the Entire Row Is Empty in Excel
Using C# Lambda to Split String and Search Value
Check If Database Exists Before Creating
Linq to SQL Left Outer Join Using Lambda Syntax and Joining on 2 Columns (Composite Join Key)