Referring to controls on other forms

  • Thread starter Thread starter Mark Rae
  • Start date Start date
M

Mark Rae

Hi,

Apologies if this is a stupid question - I'm a C# newbie... :-)

I have a Windows app with two form: frmConfigReg and frmNewApp. frmConfigReg
is the startup form. It has several controls, including a GroupBox called
grpApplications which itself contains a ComboBox called cmbApps and a button
called cmdNewApp. When cmdNewApp is clicked, it loads frmNewApp which
contains a text box where users enter the name of a new application to
configure.

However, I need to validate that the contents of this text box do not
already exist as any of the options in cmbApps on the main form.

I've tried using the following code:

Form frmConfigReg = new frmConfigReg();

but that loads a new instance of frmConfigReg, not unsurprisingly.

Can anyone please tell me how to reference controls and their properties on
another open form from within a C# windows application?

Any assistance gratefully received.

Best regards,

Mark Rae
 
Hi Mark

If you are doing this validation in the main form of your application ,
which is frmConfigReg, you don’t have to create a new instance in order to
access the ComboBox cmbApps . you simply use the this pointer .

So you write

this. cmbApps.”the name of the proparty you want to set or get”
 
Mohammed
If you are doing this validation in the main form of your application ,
which is frmConfigReg, you don't have to create a new instance in order to
access the ComboBox cmbApps . you simply use the this pointer .

So you write

this. cmbApps."the name of the proparty you want to set or get"

Yes, but I'm not - I need to to the validation on the popped up form.
Basically, I just need to know how to refer to a control on another open
form.

Mark
 
Can anyone please tell me how to reference controls and their properties
on
another open form from within a C# windows application?

You create an instance of your frmNewApp class inside your main frmConfigReg
form yes? You can supply a reference to the parent during construction:

ie. frmNewApp = new frmNewApp( this );

Where:

public class frmNewApp : System.Windows.Forms.Form
{
private frmConfigReg parent;

private frmNewApp() // Private constructor to prevent
incorrect instantiation
{
}

public frmNewApp( frmConfigReg parent )
{
this.parent = parent;
}
}

Which allows you to access to the parent object directly when validating
your contents, you can add any necessary support methods to the parent form.
There are also a number of other options such as supplying a 'validation'
delegate or interface instead of a class, but the above should be good for a
start :)

n!
 
You create an instance of your frmNewApp class inside your main frmConfigReg
form yes? You can supply a reference to the parent during construction:

ie. frmNewApp = new frmNewApp( this );

That line gives the following error:

'ConfigReg.frmNewApp' denotes a 'class' where a 'variable' was expected.

So I changed it to:

frmNewApp = new frmNewApp( this );

which, in turn, gives the following error:

No overload for method 'frmNewApp' takes '1' arguments
 
Hi Mark,

Why don't you create a public ArrayList in frmNewApp form and fill it with cmbApps values. This has to be done before showing the frmNewApp form. Then you simply validate the textbox value with values in ArrayList.
 
So I changed it to:
frmNewApp = new frmNewApp( this );

which, in turn, gives the following error:
No overload for method 'frmNewApp' takes '1' arguments

You *did* add a constructor that takes a reference to your parent form, as I
showed? :)

n!
 
Dinesh.
Why don't you create a public ArrayList in frmNewApp form and fill it with cmbApps values.
This has to be done before showing the frmNewApp form. Then you simply validate the textbox
value with values in ArrayList.

Because I don't want to. I simply want to know how to reference the
properties of controls on one open form in a C# Windows application from
another open form in the same C# Windows application - no more, no less.

I can't believe this is proving to be so tricky...

Mark
 
frmNewApp = new frmNewApp( this );

Oh I see, I was supposed to have typed:

frmNewApp child = new frmNewApp( this );

sorry.
Yep - I pretty much copied and pasted your code in directly...

it compiles on my machine fine as I typed it.

n!
 
Hi Mark

Ok you can do this :



1- Make the ComboBox cmbApps public instead of Private member of the
frmConfigReg Form.

2- Include a private member of type frmConfigReg in the second form you
have , I don’t remember its name so lets name it F2 , and lets say name
this member “themain”



private Form1 themain;

3- In the constructor of F2 , change it to take a parameter of type
frmConfigReg From … then assign this input parameter to the themain member
that you have now



public F2(Form1 caller)

{

//

themain =caller;

// Required for Windows Form Designer support

//

InitializeComponent();



//

// TODO: Add any constructor code after
InitializeComponent call

//

}

4- Back to the first form you are using, when you instantiate
frmConfigReg pass to it (this) which will be used as a reference to the
parent.



F2 second = new Form2(this);

second.Show();

5- Then you can use the mainform object in the second form F2

As F2.mainform. cmbApps.”what ever”



If this is not so clear pls confirm .

Also , notice this is not the best practice since you are making some kind
of cycle in the call stack

The best practice in such scenario is to use MDI
 
In case you want it, this is the code from my machine:

namespace temptest
{
using System;
using System.Windows.Forms;

/// <summary>
/// Summary description for Form1.
/// </summary>
public class frmConfigReg : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

public frmConfigReg()
{
// Required for Windows Form Designer support
InitializeComponent();

// Create child, passing a reference to ourself....
frmNewApp child = new frmNewApp( this );
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new System.Drawing.Size(300,300);
this.Text = "Form1";
}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new frmConfigReg());
}
}

public class frmNewApp : System.Windows.Forms.Form
{
private frmConfigReg parent;

/// <summary>
/// Private constructor to prevent incorrect instantiation.
/// </summary>
private frmNewApp()
{
}

public frmNewApp( frmConfigReg parent )
{
this.parent = parent;
}
}
}
 
In case you want it, this is the code from my machine:

Thanks.

Let's say, for the sake of argument, that we have a C# Windows application
with two forms: form1 and form2. Neither of these forms is the child or
parent of the other, and both have been opened by the app when it is
launched.

form1 has a button on it called button1

form2 has a combobox on it called comboBox1

The purpose of button1 on form1 is to add a new option to comboBox1 on form2

Can anyone please tell me how to do this?
 
If this is not so clear pls confirm .
The best practice in such scenario is to use MDI

Let's say, for the sake of argument, that we have a C# Windows application
with two forms: form1 and form2. Neither of these forms is the child or
parent of the other, and both have been opened by the app when it is
launched. It's not an MDI app, just a regular common or garden app with two
forms.

form1 has a button on it called button1

form2 has a combobox on it called comboBox1

The purpose of button1 on form1 is to add a new option to comboBox1 on form2

Can anyone please tell me how to do this?
 
Dear Mark

If you load frmNewApp form with below code in cmdNewApp's click event

frmNewApp form2 = new frmNewApp()
form2.ShowDialog(this)

you can access controls in frmConfigReg form like below

//if you know the index i
ComboBox cb = (ComboBox) ((frmConfigReg )Owner).Controls[1]

//O

ControlCollection cc = (ControlCollection) ((frmConfigReg)Owner).Controls
foreach(Control c in cc

if (c.Name=="cmbApps"

//get values and validat



hope this is what you want
 
Let's say, for the sake of argument, that we have a C# Windows application
with two forms: form1 and form2. Neither of these forms is the child or
parent of the other, and both have been opened by the app when it is
launched.

form1 has a button on it called button1

form2 has a combobox on it called comboBox1

The purpose of button1 on form1 is to add a new option to comboBox1 on form2

Can anyone please tell me how to do this?

There are many ways to achieve this, the typical way is for the main form to
respond and manage the communication between the two child forms, this
provides a more flexible architecture as you can then alter the
functionality of the form without modifying the controls (making them
reusable).

If you *really* wanted the button to communicate directly to the combo box,
then you could expose a property on each child form similar to:

[In the button1 class]

using System.Windows.Forms;

class MyButton : Button
{
private ComboBox comboTarget = null;

public ComboBox Target
{
get
{
return comboTarget;
}
set
{
comboTarget = value;
}
}

protected override void OnClick( System.EventArgs e )
{
if ( null != comboTarget )
{
// Add new options to combo box...
}

base.OnClick( e );
}
}

In the parent form, once both button and combo box have been created, you
provide your button object with the target combo box.

n!
 
There are many ways to achieve this, the typical way is for the main form to
respond and manage the communication between the two child forms, this
provides a more flexible architecture as you can then alter the
functionality of the form without modifying the controls (making them
reusable).

That's all very well, and no doubt very elegant. However, in this case,
there is no main form, nor are there any child form. There is one Windows
application with two forms, neither the parent nor the child of the other.
If you *really* wanted the button to communicate directly to the combo box,
then you could expose a property on each child form similar to:

Is there *really* no easier way of achieving what seems, to me at least, to
be an incredibly simple task...?
 
That's all very well, and no doubt very elegant. However, in this case,
there is no main form, nor are there any child form. There is one Windows
application with two forms, neither the parent nor the child of the other.

Then replace 'MainForm' with 'MainApplication' or whatever the class is that
creates these two forms :) The point being you need some sort of 'root' code
in order to create your forms, that is typically where the event handling
and communication is managed. Otherwise the forms become too specialized for
a specific task and create more work later on.
Is there *really* no easier way of achieving what seems, to me at least, to
be an incredibly simple task...?

The above *is* incredibly simple. If you mean 'can I just do this with no
programming whatsoever' then I'm afraid not, you need to specify the
relationships and how\what they communicate so a bit of code is required.

In what way would you expect to be able to do the above, in less code?
Perhaps I'm looking at the problem from the wrong angle? :)

n!
 
When you launch form1, pass the reference to the parent to the constructor
of form1.

public class Mother
{
private form2 f2;

public Mother()
{
form1 f1 = new form1(this);
f2 = new form();
}

public void PassAlong(string option)
{
f2.AddNewOption(option);
}
}

public class form1
{
private Mother parent;

public form1(Mother caller)
{
parent = caller;
}

button1_Click(...)
{
parent.PassAlong("somenewvalue");
}
}

public class form2
{
public form2()
{
{

public void AddNewOption(string newOption)
{
comboBox1.Items.Add(newOption);
}
}

Parent holds reference to form2, and form1 holds a reference to the parent.
I don't particularly like all the public methods though, but this will do
what you need without exposing the controls themselves.
 
Back
Top