<p>First off, this is a question about a desktop application using Windows Forms, not an <a href="http://en.wikipedia.org/wiki/ASP.NET" rel="nofollow noreferrer">ASP.NET</a> question.</p>

<p>I need to interact with controls on other forms. I am trying to access the controls by using, for example, the following...</p>

<pre><code>otherForm.Controls["nameOfControl"].Visible = false;
</code></pre>

<p>It doesn't work the way I would expect. I end up with an exception thrown from <code>Main</code>. However, if I make the controls <code>public</code> instead of <code>private</code>, I can then access them directly, as so...</p>

<pre><code>otherForm.nameOfControl.Visible = false;
</code></pre>

<p>But is that the best way to do it? Is making the controls <code>public</code> on the other form considered "best practice"? Is there a "better" way to access controls on another form?</p>

<p><strong>Further Explanation:</strong></p>

<p>This is actually a sort of follow-up to another question I asked, <em><a href="https://stackoverflow.com/questions/3725/best-method-for-creating-a-tree-view-preferences-dialog-type-of-interface-in-c">Best method for creating a “tree-view preferences dialog” type of interface in C#?</a></em>. The answer I got was great and solved many, many organizational problems I was having in terms of keeping the UI straight and easy to work with both in run-time and design-time. However, it did bring up this one niggling issue of easily controlling other aspects of the interface.</p>

<p>Basically, I have a root form that instantiates a lot of other forms that sit in a panel on the root form. So, for instance, a radio button on one of those sub-forms might need to alter the state of a status strip icon on the main, root form. In that case, I need the sub-form to talk to the control in the status strip of the parent (root) form. (I hope that makes sense, not in a "who's on first" kind of way.)</p>

[{'answer_id': 8567, 'author': 'Rob Cooper', 'author_id': 832, 'author_profile': 'https://Stackoverflow.com/users/832', 'pm_score': 4, 'selected': False, 'text': "<p>I personally would recommend <em>NOT</em> doing it... If it's responding to some sort of action and it needs to change its appearance, I would prefer raising an event and letting it sort itself out...</p>\n\n<p>This kind of coupling between forms always makes me nervous. I always try to keep the UI as light and <em>independent</em> as possible..</p>\n\n<p>I hope this helps. Perhaps you could expand on the scenario if not?</p>\n"}, {'answer_id': 8572, 'author': 'Ed S.', 'author_id': 1053, 'author_profile': 'https://Stackoverflow.com/users/1053', 'pm_score': 2, 'selected': False, 'text': '<p>I would handle this in the parent form.  You can notify the other form that it needs to modify itself through an event.</p>\n'}, {'answer_id': 8573, 'author': 'Jon Limjap', 'author_id': 372, 'author_profile': 'https://Stackoverflow.com/users/372', 'pm_score': 5, 'selected': False, 'text': "<p>Instead of making the control public, you can create a property that controls its visibility:</p>\n\n<pre><code>public bool ControlIsVisible\n{\n     get { return control.Visible; }\n     set { control.Visible = value; }\n}\n</code></pre>\n\n<p>This creates a proper accessor to that control that won't expose the control's whole set of properties.</p>\n"}, {'answer_id': 8574, 'author': 'Biri', 'author_id': 968, 'author_profile': 'https://Stackoverflow.com/users/968', 'pm_score': 3, 'selected': False, 'text': '<p>The first is not working of course. The controls on a form are private, visible only for that form by design.</p>\n\n<p>To make it all public is also not the best way.</p>\n\n<p>If I would like to expose something to the outer world (which also can mean an another form), I make a public property for it.</p>\n\n<pre><code>public Boolean nameOfControlVisible\n{\n    get { return this.nameOfControl.Visible; }\n    set { this.nameOfControl.Visible = value; }\n}\n</code></pre>\n\n<p>You can use this public property to hide or show the control or to ask the control current visibility property:</p>\n\n<pre><code>otherForm.nameOfControlVisible = true;\n</code></pre>\n\n<p>You can also expose full controls, but I think it is too much, you should make visible only the properties you really want to use from outside the current form.</p>\n\n<pre><code>public ControlType nameOfControlP\n{\n    get { return this.nameOfControl; }\n    set { this.nameOfControl = value; }\n}\n</code></pre>\n'}, {'answer_id': 8579, 'author': 'Biri', 'author_id': 968, 'author_profile': 'https://Stackoverflow.com/users/968', 'pm_score': 3, 'selected': False, 'text': '<p>After reading the additional details, I agree with <a href="https://stackoverflow.com/questions/8566/best-way-to-access-a-control-on-another-form-in-c?sort=Newest#8567">robcthegeek</a>: raise an event. Create a custom EventArgs and pass the neccessary parameters through it.</p>\n'}, {'answer_id': 8590, 'author': 'Ed S.', 'author_id': 1053, 'author_profile': 'https://Stackoverflow.com/users/1053', 'pm_score': 0, 'selected': False, 'text': '<p>Do your child forms really need to be Forms?  Could they be user controls instead?  This way, they could easily raise events for the main form to handle and you could better encapsulate their logic into a single class (at least, logically, they are after all classes already).</p>\n\n<p>@Lars:  You are right here.  This was something I did in my very beginning days and have not had to do it since, that is why I first suggested raising an event, but my other method would really break any semblance of encapsulation.</p>\n\n<p>@Rob: Yup, sounds about right :).  0/2 on this one...</p>\n'}, {'answer_id': 8592, 'author': 'Rob Cooper', 'author_id': 832, 'author_profile': 'https://Stackoverflow.com/users/832', 'pm_score': 0, 'selected': False, 'text': "<p>@Lars, good call on the passing around of Form references, seen it as well myself. Nasty. Never seen them passed them down to the BLL layer though! That doesn't even make sense! That could have seriously impacted performance right? If somewhere in the BLL the reference was kept, the form would stay in memory right?</p>\n\n<p>You have my sympathy! ;)</p>\n\n<hr>\n\n<p>@Ed, RE your comment about making the Forms UserControls. Dylan has already pointed out that the root form instantiates <em>many</em> child forms, giving the impression of an MDI application (where I am assuming users may want to close various Forms). If I am correct in this assumption, I would think they would be best kept as forms. Certainly open to correction though :)</p>\n"}, {'answer_id': 8895, 'author': 'Patrik Svensson', 'author_id': 936, 'author_profile': 'https://Stackoverflow.com/users/936', 'pm_score': 1, 'selected': False, 'text': '<p>I agree with using events for this. Since I suspect that you\'re building an MDI-application (since you create many child forms) and creates windows dynamically and might not know when to unsubscribe from events, I would recommend that you take a look at <a href="http://msdn.microsoft.com/en-us/library/aa970850.aspx" rel="nofollow noreferrer">Weak Event Patterns</a>. Alas, this is only available for framework 3.0 and 3.5 but something similar can be implemented fairly easy with weak references.</p>\n\n<p>However, if you want to find a control in a form based on the form\'s reference, it\'s not enough to simply look at the form\'s control collection. Since every control have it\'s own control collection, you will have to recurse through them all to find a specific control. You can do this with these two methods (which can be improved).</p>\n\n<pre><code>public static Control FindControl(Form form, string name)\n{\n    foreach (Control control in form.Controls)\n    {\n        Control result = FindControl(form, control, name);\n\n        if (result != null)\n            return result;\n    }\n\n    return null;\n}\n\nprivate static Control FindControl(Form form, Control control, string name)\n{\n    if (control.Name == name) {\n        return control;\n    }\n\n    foreach (Control subControl in control.Controls)\n    {\n        Control result = FindControl(form, subControl, name);\n\n        if (result != null)\n            return result;\n    }\n\n    return null;\n}\n</code></pre>\n'}, {'answer_id': 13453, 'author': 'Chris Hanson', 'author_id': 714, 'author_profile': 'https://Stackoverflow.com/users/714', 'pm_score': 0, 'selected': False, 'text': '<p>You should only ever access one view\'s contents from another if you\'re creating more complex controls/modules/components.  Otherwise, you should do this through the standard Model-View-Controller architecture:  You should connect the enabled state of the controls you care about to some model-level predicate that supplies the right information.</p>\n\n<p>For example, if I wanted to enable a Save button only when all required information was entered, I\'d have a predicate method that tells when the model objects representing that form are in a state that can be saved.  Then in the context where I\'m choosing whether to enable the button, I\'d just use the result of that method.</p>\n\n<p>This results in a much cleaner separation of business logic from presentation logic, allowing both of them to evolve more independently — letting you create one front-end with multiple back-ends, or multiple front-ends with a single back-end with ease.</p>\n\n<p>It will also be much, much easier to write unit and acceptance tests for, because you can follow a "<a href="http://chanson.livejournal.com/118380.html" rel="nofollow noreferrer" title="Trust But Verify for UI testing">Trust But Verify</a>" pattern in doing so:</p>\n\n<ol>\n<li><p>You can write one set of tests that set up your model objects in various ways and check that the "is savable" predicate returns an appropriate result.</p></li>\n<li><p>You can write a separate set of that check whether your Save button is connected in an appropriate fashion to the "is savable" predicate (whatever that is for your framework, in Cocoa on Mac OS X this would often be through a binding).</p></li>\n</ol>\n\n<p>As long as both sets of tests are passing, you can be confident that your user interface will work the way you want it to.</p>\n'}, {'answer_id': 48648, 'author': 'Garo Yeriazarian', 'author_id': 2655, 'author_profile': 'https://Stackoverflow.com/users/2655', 'pm_score': 0, 'selected': False, 'text': "<p>This looks like a prime candidate for separating the presentation from the data model.  In this case, your preferences should be stored in a separate class that fires event updates whenever a particular property changes (look into INotifyPropertyChanged if your properties are a discrete set, or into a single event if they are more free-form text-based keys).</p>\n\n<p>In your tree view, you'll make the changes to your preferences model, it will then fire an event.  In your other forms, you'll subscribe to the changes that you're interested in.  In the event handler you use to subscribe to the property changes, you use this.InvokeRequired to see if you are on the right thread to make the UI call, if not, then use this.BeginInvoke to call the desired method to update the form.</p>\n"}, {'answer_id': 746967, 'author': 'Davorin', 'author_id': 42831, 'author_profile': 'https://Stackoverflow.com/users/42831', 'pm_score': 1, 'selected': False, 'text': "<p>You can</p>\n\n<ol>\n<li>Create a public method with needed parameter on child form and call it from parent form (with valid cast)</li>\n<li>Create a public property on child form and access it from parent form (with valid cast)</li>\n<li>Create another constructor on child form for setting form's initialization parameters</li>\n<li>Create custom events and/or use (static) classes</li>\n</ol>\n\n<p>Best practice would be #4 if you are using non-modal forms.</p>\n"}, {'answer_id': 5996830, 'author': 'eduardolucioac', 'author_id': 751174, 'author_profile': 'https://Stackoverflow.com/users/751174', 'pm_score': 1, 'selected': False, 'text': '<p>With the property (highlighted) I can get the instance of the MainForm class. But this is a good practice? What do you recommend? </p>\n\n<p>For this I use the property MainFormInstance that runs on the OnLoad method.</p>\n\n<pre><code>using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing LightInfocon.Data.LightBaseProvider;\nusing System.Configuration;\n\nnamespace SINJRectifier\n{\n\n    public partial class MainForm : Form\n    {\n        public MainForm()\n        {\n            InitializeComponent();\n        }\n\n        protected override void OnLoad(EventArgs e)\n        {\n            UserInterface userInterfaceObj = new UserInterface();\n            this.chklbBasesList.Items.AddRange(userInterfaceObj.ExtentsList(this.chklbBasesList));\n            MainFormInstance.MainFormInstanceSet = this; //Here I get the instance\n        }\n\n        private void btnBegin_Click(object sender, EventArgs e)\n        {\n            Maestro.ConductSymphony();\n            ErrorHandling.SetExcecutionIsAllow();\n        }\n    }\n\n    static class MainFormInstance  //Here I get the instance\n    {\n        private static MainForm mainFormInstance;\n\n        public static MainForm MainFormInstanceSet { set { mainFormInstance = value; } }\n\n        public static MainForm MainFormInstanceGet { get { return mainFormInstance; } }\n    }\n}\n</code></pre>\n'}, {'answer_id': 6446864, 'author': 'user811204', 'author_id': 811204, 'author_profile': 'https://Stackoverflow.com/users/811204', 'pm_score': 2, 'selected': False, 'text': "<ol>\n<li>Use an event handler to notify other the form to handle it.</li>\n<li>Create a public property on the child form and access it from parent form (with a valid cast).</li>\n<li>Create another constructor on the child form for setting form's initialization parameters</li>\n<li>Create custom events and/or use (static) classes.</li>\n</ol>\n\n<p>The best practice would be #4 if you are using non-modal forms.</p>\n"}, {'answer_id': 6517677, 'author': 'Santosh Lodhi', 'author_id': 807788, 'author_profile': 'https://Stackoverflow.com/users/807788', 'pm_score': 0, 'selected': False, 'text': '<p>Step 1:</p>\n\n<pre><code>string regno, exm, brd, cleg, strm, mrks, inyear;\n\nprotected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)\n{\n    string url;\n    regno = GridView1.Rows[e.NewEditIndex].Cells[1].Text;\n    exm = GridView1.Rows[e.NewEditIndex].Cells[2].Text;\n    brd = GridView1.Rows[e.NewEditIndex].Cells[3].Text;\n    cleg = GridView1.Rows[e.NewEditIndex].Cells[4].Text;\n    strm = GridView1.Rows[e.NewEditIndex].Cells[5].Text;\n    mrks = GridView1.Rows[e.NewEditIndex].Cells[6].Text;\n    inyear = GridView1.Rows[e.NewEditIndex].Cells[7].Text;\n\n    url = "academicinfo.aspx?regno=" + regno + ", " + exm + ", " + brd + ", " +\n          cleg + ", " + strm + ", " + mrks + ", " + inyear;\n    Response.Redirect(url);\n}\n</code></pre>\n\n<p>Step 2:</p>\n\n<pre><code>protected void Page_Load(object sender, EventArgs e)\n{\n    if (!IsPostBack)\n    {\n        string prm_string = Convert.ToString(Request.QueryString["regno"]);\n\n        if (prm_string != null)\n        {\n            string[] words = prm_string.Split(\',\');\n            txt_regno.Text = words[0];\n            txt_board.Text = words[2];\n            txt_college.Text = words[3];\n        }\n    }\n}\n</code></pre>\n'}, {'answer_id': 9079357, 'author': 'KARAN', 'author_id': 1180288, 'author_profile': 'https://Stackoverflow.com/users/1180288', 'pm_score': 2, 'selected': False, 'text': '<p>Suppose you have two forms, and you want to hide the property of one form via another:</p>\n\n<pre><code>form1 ob = new form1();\nob.Show(this);\nthis.Enabled= false;\n</code></pre>\n\n<p>and when you want to get focus back of form1 via form2 button then:</p>\n\n<pre><code>Form1 ob = new Form1();\nob.Visible = true;\nthis.Close();\n</code></pre>\n'}, {'answer_id': 38985293, 'author': 'Mansoor Bozorgmehr', 'author_id': 4145647, 'author_profile': 'https://Stackoverflow.com/users/4145647', 'pm_score': 0, 'selected': False, 'text': "<p>Change modifier from public to internal. .Net deliberately uses private modifier instead of the public, due to preventing any illegal access to your methods/properties/controls out of your project. In fact, public modifier can accessible wherever, so They are really dangerous. Any body out of your project can access to your methods/properties. But In internal modifier no body (other of your current project) can access to your methods/properties.</p>\n\n<p>Suppose you are creating a project, which has some secret fields. So If these fields being accessible out of your project, it can be dangerous, and against to  your initial ideas. As one good recommendation, I can say always use internal modifier instead of public modifier.</p>\n\n<p>But some strange!</p>\n\n<p>I must tell also in VB.Net while our methods/properties are still private, it can be accessible from other forms/class by calling form as a variable with no any problem else. </p>\n\n<p>I don't know why in this programming language behavior is different from C#. As we know both are using same Platform and they claim they are almost same Back end Platform, but as you see, they still behave differently.</p>\n\n<p>But I've solved this problem with two approaches. Either; by using Interface (Which is not a recommend, as you know, Interfaces usually need public modifier, and using a public modifier is not recommend (As I told you above)), </p>\n\n<p>Or </p>\n\n<p>Declare your whole Form in somewhere static class and static variable and there is still internal modifier. Then when you suppose to use that form for showing to users, so pass new <code>Form()</code> construction to that static class/variable. Now It can be Accessible every where as you wish. But you still need some thing more. \nYou declare your element internal modifier too in Designer File of Form. While your Form is open, it can be accessible everywhere. It can work for you very well.</p>\n\n<p>Consider This Example.</p>\n\n<p>Suppose you want to access to a Form's TextBox. </p>\n\n<p>So the first job is declaration of a static variable in a static class (The reason of static is ease of access without any using new keywork at future). </p>\n\n<p>Second go to designer class of that Form which supposes to be accessed by other Forms. Change its TextBox modifier declaration from private to internal. Don't worry; .Net never change it again to private modifier after your changing.</p>\n\n<p>Third when you want to call that form to open, so pass the new Form Construction  to that static variable-->>static class.</p>\n\n<p>Fourth;  from any other Forms (wherever in your project) you can access to that form/control while From is open.</p>\n\n<p>Look at code below (We have three object. \n1- a static class (in our example we name it <code>A</code>) </p>\n\n<p>2 - Any Form else which wants to open the final Form (has TextBox, in our example <code>FormB</code>). </p>\n\n<p>3 - The real Form which we need to be opened, and we suppose to access to its internal <code>TextBox1</code> (in our example <code>FormC</code>). </p>\n\n<p>Look at codes below:</p>\n\n<pre><code>internal static class A\n{\n    internal static FormC FrmC;\n}\n\nFormB ...\n{\n    '(...)\n    A.FrmC = new FormC();\n    '(...)\n}\n\nFormC (Designer File) . . . \n{\n     internal System.Windows.Forms.TextBox TextBox1;\n}\n</code></pre>\n\n<p>You can access to that static Variable (here <code>FormC</code>) and its internal control (here <code>Textbox1</code>) wherever and whenever as you wish, while <code>FormC</code> is open.</p>\n\n<hr>\n\n<p>Any Comment/idea let me know. I glad to hear from you or any body else about this topic more. Honestly I have had some problems regard to this mentioned problem in past. The best way was the second solution that I hope it can work for you.  Let me know any new idea/suggestion. </p>\n"}, {'answer_id': 44167938, 'author': 'user7993881', 'author_id': 7993881, 'author_profile': 'https://Stackoverflow.com/users/7993881', 'pm_score': 0, 'selected': False, 'text': '<pre><code>public void Enable_Usercontrol1()\n{\n    UserControl1 usercontrol1 = new UserControl1();\n    usercontrol1.Enabled = true;\n} \n/*\n    Put this Anywhere in your Form and Call it by Enable_Usercontrol1();\n    Also, Make sure the Usercontrol1 Modifiers is Set to Protected Internal\n*/\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/8566', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/551/']