views:

4837

answers:

3

Good day everyone,

I am building a page in ASP.NET, and using Master Pages in the process.

I have a Content Place Holder name "cphBody" in my Master Page, which will contain the body of each Page for which that Master Page is the Master Page.

In the ASP.NET Web page, I have a Content tag (referencing "cphBody") which also contains some controls (buttons, Infragistics controls, etc.), and I want to access these controls in the CodeBehind file. However, I can't do that directly (this.myControl ...), since they are nested in the Content tag.

I found a workaround with the FindControl method.

ContentPlaceHolder contentPlaceHolder = (ContentPlaceHolder) Master.FindControl("cphBody");
ControlType myControl = (ControlType) contentPlaceHolder.FindControl("ControlName");

That works just fine. However, I am suspecting that it's not a very good design. Do you guys know a more elegant way to do so?

Thank you!

Guillaume Gervais.

A: 

I use this code for acess to files recursively:

    /// <summary>
    /// Recursively iterate through the controls collection to find the child controls of the given control
    /// including controls inside child controls. Return all the IDs of controls of the given type 
    /// </summary>
    /// <param name="control"></param>
    /// <param name="controlType"></param>
    /// <returns></returns>
    public static List<string> GetChildControlsId(Control control, Type controlType)
    {
        List<string> FoundControlsIds = new List<string>();
        GetChildControlsIdRecursive(FoundControlsIds, control, controlType);

        // return the result as a generic list of Controls
        return FoundControlsIds;
    }

    public static List<string> GetChildControlsIdRecursive(List<string> foundControlsIds, Control control, Type controlType)
    {
        foreach (Control c in control.Controls)
        {
            if (controlType == null || controlType.IsAssignableFrom(c.GetType()))
            {
                // check if the control is already in the collection
                String FoundControl = foundControlsIds.Find(delegate(string ctrlId) { return ctrlId == c.ID; });

                if (String.IsNullOrEmpty(FoundControl))
                {
                    // add this control and all its nested controls
                    foundControlsIds.Add(c.ID);
                }
            }

            if (c.HasControls())
            {
                GetChildControlsIdRecursive(foundControlsIds, c, controlType);
            }
        }
pho3nix
+1  A: 

Rick Strahl has a good explanation (and sample code) here - http://www.west-wind.com/Weblog/posts/5127.aspx

Duncan
Thank you! That's basically what I did, so it validates my method for me!
Guillaume Gervais
+2  A: 

How about including the path to your master page at the top of your child page

<%@ MasterType VirtualPath="~/MasterPages/PublicUI.Master" %>

Which will allow you to directly call code from your master page code behind.

Then from your master page code behind you could make a property return your control, or make a method on the master page get your control etc.

        public Label SomethingLabel
        {
            get { return lblSomething; }
        }

Refers to

<asp:Label ID="lblSomething" runat="server" />

Usage:

Master.SomethingLabel.Text = "some text";
CRice