Interform Control Access

Geekitygeek 3 Tallied Votes 1K Views Share

This seems to be coming up in a LOT of posts at the moment so i figured i would put it into a handy code snippet to save us keep typing it.
To access controls on a form you need to have a reference to the current instance of that form.
The easiest way to do this is to pass a reference to the "parent" form into the "child" form when you instantiate it.

By passing a reference to the parent into the child, the child can then access all the public members of the parent through that reference.

A point of note; i have used a read only property to access the text property of the textbox. Some people suggest making the control public but this violates the OO design principles of Encapsulation.
By only allowing access to internal members via properties you can a) control and validate the data passed in and out of the class and b) alter the internal workings of the class without impacting on external classes which access its members.

Lusiphur commented: Excellently written example +1
Duki commented: Finally - thanks! +7
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Form2 frm2 = new Form2(this); //pass reference to this form in constructor
        }

        public string TextBoxText //read only property to access textbox text
        {
            get { return textBox1.Text; }
        }
    }

    public partial class Form2 : Form
    {
        Form1 frm1;
        public Form2(Form1 callingForm)
        {
            InitializeComponent();
            frm1 = callingForm;  //store local reference to Form1
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            this.textBox1.Text = frm1.TextBoxText; //use reference to Form1 to access property
        }
    }
ddanbe 2,724 Professional Procrastinator Featured Poster

There is indeed much need for things like this!
Very well explained also.
Keep up the good work. ;)

jayxx1234 0 Newbie Poster

Also note (I just found this out) that if you want to call a method from another form, then put:

internal void MethodName()
{
doSomething;
}

for creating the method. Then to call it from another form, simply put:

frm1.MethodName();

(or whatever you have called your reference to the other form) once you have given it a reference in your second form.

Geekitygeek 480 Nearly a Posting Virtuoso

That's not entirely true. The access modifier you use depends on your design. Using internal ensures that the method can only be accessed within the same assembly, not by external objects whilst public is accessible by almost anything.

jayxx1234 0 Newbie Poster

Internal is less visible from the outside, so has less chance of being used by an unauthorised user. But like you said, it depends on your design, and what you intend to do in your code. Personally, I use the least hackable, as I am a newbie to programming and computer networks, and so I am more prone to unknowingly letting a hacker in.

Tailean 0 Newbie Poster

Where does the code go? does some of it go in form 2 and some in form 1? if so what parts where?

jayxx1234 0 Newbie Poster

@Tailean the MethodName goes wherever you want your method to go. Then to call it from another form than the one it is declared in, you put the calling statement nameOfOtherForm.MethodName() in the second form. For instance, say in Form1 I have this:

internal void UpdateDisplay()
{
label1.Text = "whatever";
pictureBox.Refresh();
}

Then, say I want to call this method from Form2, then in Form2 I would put:

Form1.UpdateDisplay();

NOTE: You have to put a Form1 reference in the form constructor:

Form1 frm1;
        public Form2(Form1 callingForm)
        {
            InitializeComponent();
            frm1 = callingForm;  //store local reference to Form1
        }
jayxx1234 0 Newbie Poster

The same applies to Dan Parr's snippet above. When accessing stuff between forms, use his code and apply it to whatever situation you want. Which form they are in doesnt matter, but if they are in the same form, you are reading the wrong thread. Note, you need to put both a form reference (to whatever form your code to call is in), and a form passer, eg in Form1, when I want to display Form2, I put:

Form2 frm2 = new Form2(this); //passes reference to Form1
frm2.Show();

Then do:

Form1 frm1;
public Form2(Form1 callingForm)
{
InitializeComponent
frm1 = callingForm;

The first snippet passes a reference to Form1 to the second snippet, which assigns it a place in memory, called frm1. You can then put

frm1.MethodName();

and it will execute the code in Form1's MethodName() method.
This code also (as seen in Dan Parr's code) gives access to any other element of Form1 (or whichever form you use).

ashishkumar008 2 Light Poster

marked textbox with public keyword and also use a static variable to store textbox data.
now you can use this textbox and it's data in next or other forms.

beetscodes 0 Newbie Poster

I thought that an event handler would be a better choice than to pass a reference of the parent.

When should I choose to use an event handler? Why shouldn't I use one here?

jayxx1234 0 Newbie Poster

What event handler would you use? I dont know of any that could accomplish the same task.

beetscodes 0 Newbie Poster

What event handler would you use? I dont know of any that could accomplish the same task.

You would write your own event on the form that you call and then run any internal method or change any internal control that you wish without exposing them.


Something like this:

namespace frmDialog
{ 
    public partial class frmDialog : Form
    {
        private bool userClick = false;
        private String newText = null;

        private void frmDialog_Load(object sender, String loadText)
        {
            this.TextBox.Text = loadText;
        }

        //Code enabling your own event on this form//
        public delegate void DialogClosed(object sender, frmDialogEventArgs e);
        public event DialogClosed dialogClosed;
        protected virtual void RaiseEvent(frmDialogEventArgs e)
        {
            if (dialogClosed != null)
                dialogClosed(this, e);
        }
        //Code enabling your own event on this form//
        
        //What you do here and when you raise the event is up to you//
        private void process_Click(object sender, EventArgs e)
        {
            Control ctrl = sender as Control;
            if (ctrl.Text == "Yes")
                userClick = true;
            this.Close();
        }
        private void form_Closing(object sender, FormClosingEventArgs e)
        {
            RaiseEvent(new frmDialogEventArgs(userClick, newText));
        }
        //What you do here and when you raise the event is up to you//

        //The variables you will send with the event when you raise it//
        public sealed class frmDialogEventArgs : EventArgs
        {
                private readonly bool _value;
	        private readonly String _newText;
	        public frmDialogEventArgs(bool value, String newText)
	        {
	            this._value = value;
	            this._newText= newText;
	        }
	        public bool UserClick { get { return value; } }
	        public String NewText { get { return newText; } }
	    }
        //The variables you will send with the event when you raise it//
}


namespace frmParent
{ 
    public partial class frmDialog : Form
    {
        private void loadDialog(object sender, String loadText)
        {
            frmDialog ofrmDialog = new frmDialog(sender, loadText);
            ofrmDialog.dialogClosed += new frmDialog.DialogClosed(ofrmDialog_dialogClosed);
        }

        private void ofrmDialog_dialogClosed(object sender, frmDialogEventArgs e)
        {
            if (e.UserClick)
            {
               this.Ctrl.Text = e.NewText;
            }
            else
            {
                this.Any_Other_Parent_Method_Accessing_Any_Parent_Controls_And_Variables();
            }
        }

        private void Any_Other_Parent_Method_Accessing_Any_Parent_Controls_And_Variables()
        {
            //As you wish.
        }
    }
}
jayxx1234 0 Newbie Poster

From reading this, it seems to me that it would work, and if it does, i guess it would be better than my way. I didnt know you could create your own events. Thanks for the example, that helps heaps.

beetscodes 0 Newbie Poster

From reading this, it seems to me that it would work, and if it does, i guess it would be better than my way. I didnt know you could create your own events. Thanks for the example, that helps heaps.

I think that once you start using it you will like how it works.

cheers

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.