C# .NET - Refer to Parent Control From User Control

Asked By Craig Vedur on 17-Feb-06 03:44 PM
Hi,

I have a win form that has a custom User Control on it that I created , along w/ a textbox.

How can I write something to the text box from action within the user control.

Essentially, in my user control, I have a button btnSend.  When I click btnSend, I want to write "Hello" to the textbox named "TB" on the parent form.

Any ideas how to do this elegantly?

An efficient way to handle this: - Asked By Peter Bromberg on 17-Feb-06 04:28 PM

1) Overload the ctor to your control to accept an instance of the parent form.
2) in the ctor, populate the form field:

// ctor
public MyControl( Form parentForm)
{

this.ParentForm = parentForm;

}

// now you have access to the parent Form instance from within the control.


So you would do this from parent:

MyControl ctrl = new MyControl(this);

What would I do for design time, not run time? - Asked By Craig Vedur on 19-Feb-06 11:06 AM

Instead of creating my controls at runtime, I placed them on the form at design time.  Will this logic still work?  

Or , is there an alternative?

I guess it still places a constructor on the page in the 'win generated code'

So, maybe i just answered my own question

thanks pete

Use Events - its the most elegant and scalable by - Asked By Jason Coyne on 20-Feb-06 04:22 PM

The most elegant way to do this is via events. Events keep the black box model of development going, in that the page/form does not have to have any special design to use your control correctly.  It either listens to the event, or it doesn't.  Additionally events allow you to bind to your form at design time.  If you go down the route that you were initially thinking, or that some of the other posters said, if forces the page to have a TB textbox on the page.  If I want to use the control, but my textbox is named "Superman", or I want to pop up a messagebox instead, then your control is useless.

The events code is slightly longer, but infinitely more powerful.

Here is an example of some an event I raise in one of my ASP.net forms.  Very simmilar code will work with no problems in winforms.
Put this first snippet anywhere inside your namespace (but not inside any other class)


[CODE]
//Create a new event handler delegate, so that you can pass information back to the form. You could use the standard EventHandler, but then you can't pass any info back.
 public delegate void SearchUpdateEventHandler(object sender, SearchUpdateEventArgs e);

//Here is a class that you use to hold the info that gets passed back. It has to decend from EventArgs.
    public class SearchUpdateEventArgs : EventArgs
    {
        public SearchQuery searchQuery;

        public SearchUpdateEventArgs(SearchQuery searchQuery)
        {
            this.searchQuery = searchQuery;
        }
    }
[/CODE]

Then, in your control, have the following code

[CODE]
//Create the event so your form can listen for it
public event SearchUpdateEventHandler UpdateSearchCriteria;

//In your button/link, raise the event back to the form.
 private void lnk_Click(object sender, EventArgs e)
        {
            searchQuery.SearchText += " " + ((LinkButton) sender).Text;
            Results = searchQuery.Search();

            //This line makes it so you only raise the event if someone is listening.
            if (UpdateSearchCriteria!=null)
                //Raise the event, and pass in the data (searchQuery in this case) that you want to send to the form.

                UpdateSearchCriteria(this, new SearchUpdateEventArgs(searchQuery));
        }
[/CODE]

Finally, in your main form, you have code that listens for the event.  This is just like any other event you have on your form for buttons etc.

These last two snippets can be generated automatically using the events (lightning bolt) button on the properties window at design time.

Put this line of code somewhere in your onLoad (or the winforms equivilent)
[CODE]
SearchResultDisplay3.UpdateSearchCriteria+=new SearchUpdateEventHandler(SearchResultDisplay3_UpdateSearchCriteria);
[/CODE]

and then your actual event (just like normal buttons)

[CODE]
  private void SearchResultDisplay3_UpdateSearchCriteria(object sender, SearchUpdateEventArgs e)
        {
//Or set your textbox or whatever
            SearchCriteria1.UpdateForm(e.searchQuery);
        }

[/CODE]
Michel replied to Craig Vedur on 26-Oct-10 11:09 AM
Although my answer is too late, I will put it for anyone who may have this question now or later.
The best way to retrieve the parent of the user control is to use the ParentChanged event of the user control.  This event belongs to the Control object; so all controls inherit this event.  This event is fired once when you drop the user control on the Form or any container like a GroupBox.  It is also fired once again when the Form is run.  Here's the VB code to get the parent of the user control (as I'm not quite sure of the C# code):

' The code below is in the UserControl object:

' Declare a Form object at class-level:

Dim gFrm As Form


' The ParentChanged event of the user control.

Private Sub TextBox_ParentChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ParentChanged

     If TypeOf Me.Parent Is Form Then

      gFrm = CType(Me.Parent, Form)       ' Something like this in C#:   gFrm = (Form) this.Parent

    End If
End Sub



NB:
1-The TypeOf keyword in VB is not the same as that in C#.  In VB, TypeOf checks the type of the object, while in C#, TypeOf gets the type of the object.  So, you have to use the appropriate C# keyword that checks the type of the parent.  Checking the type of the parent is important because it may not be necessarily a form.

2-The Me keyword in VB is the same as this in C#.

3-The CType operator performs a conversion between types.

4-After the code above, make sure you test whether gFrm is null before using it.