Solved

Why can't I use findcontrol to dynamically locate a control that I can see in 'this'

Posted on 2011-03-15
10
604 Views
Last Modified: 2013-12-17
I am trying to dynamically allocate information to a group of placeholders on an asp page that uses a Masterpage.

I have 6 placeholders named Placeholder1 to PlaceHolder6 and I want to add a usercontrol containing a table with a header text label, an image and a button in as many as are required depending on data driving it.

Then I want to customise each usercontrol's headerlabel text, image and button text depending on variables from the driving data.

My problem is that although in debug I can see this.placeholder1 etc, I can't seem to find them using findcontrol.

Here is the page :

<%@ Page Language="C#" MasterPageFile="~/Templates/SitePage.Master" AutoEventWireup="true"
    CodeBehind="SelectTemplate.aspx.cs" Inherits="MM.MailCampaign.Web.Campaign.SelectTemplate"
    Title="Step 2 | Select your template | zzz Touch" %>

<asp:Content ID="Content1" ContentPlaceHolderID="Header" runat="server">
    <asp:Label ID="HeadingLabel" CssClass="Header" Text="Create a Mailing" runat="server"></asp:Label>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <table border="0" cellpadding="0" cellspacing="0" width="100%">
        <tr>
            <td colspan="2">
                &nbsp;
            </td>
        </tr>
        <tr>
            <td>
                <table border="0" cellpadding="0" cellspacing="0" class="TabsTemplate">
                    <tr>
                        <td width="6">
                        </td>
                        <td align="center">
                            <asp:HyperLink ID="SigLink" runat="server" CssClass="TabsLinkRed" Text="Touch Mail"
                                NavigateUrl="~/Campaign/SelectTemplate.aspx"></asp:HyperLink>
                        </td>
                        <td align="center">
                            &nbsp;<asp:Label ID="Emails" runat="server" CssClass="Disabled" Text="Touch emails (available soon)"></asp:Label>
                        </td>
                        <td align="center">
                            <asp:Label ID="TxT" runat="server" CssClass="Disabled" Text="Touch TXT (available soon)"></asp:Label>
                        </td>
                    </tr>
                </table>
                <table border="0" cellpadding="0" cellspacing="0" width="100%" class="OuterTable">
                    <tr>
                        <td>
                            &nbsp;
                        </td>
                    </tr>
                    <tr>
                        <td align="left">
                            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                                <tr>
                                    <td style="padding-left: 10px">
                                        <asp:Label ID="SubHeadingLabel" CssClass="SubHeading" runat="server" Text="Select your template"></asp:Label>
                                    </td>
                                    <td align="right" style="padding-right: 10px" colspan="2">
                                        <asp:Label ID="MailingForLabel" runat="server" CssClass="TextBold"></asp:Label>
                                    </td>
                                    <td align="right" width="90px">
                                        <asp:Image ID="SelectedImage" runat="server" ImageUrl="~/images/SelectedTwo.jpg" />
                                    </td>
                                    <td width="10px">
                                        &nbsp;
                                    </td>
                                </tr>
                            </table>
                        </td>
                    </tr>
                    <tr>
                        <td style="padding: 10px 10px 10px 10px" valign="top">
                            <table border="0" cellpadding="0" cellspacing="0" width="100%">
                                <tr>
                                    <td>
                                        &nbsp;<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
                                    </td>
                                    <td width="10">
                                        &nbsp;
                                    </td>
                                    <td>
                                        &nbsp;<asp:PlaceHolder ID="PlaceHolder2" runat="server"></asp:PlaceHolder>
                                    </td>
                                    <td width="10">
                                        &nbsp;
                                    </td>
                                    <td>
                                        &nbsp;<asp:PlaceHolder ID="PlaceHolder3" runat="server"></asp:PlaceHolder>
                                    </td>
                                </tr>
                                <tr>
                                    <td colspan="5">
                                        <table width="100%">
                                            <tr>
                                                <td height="5px">
                                                </td>
                                            </tr>
                                        </table>
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        &nbsp;<asp:PlaceHolder ID="PlaceHolder4" runat="server"></asp:PlaceHolder>
                                    </td>
                                    <td width="10">
                                        &nbsp;
                                    </td>
                                    <td>
                                        <asp:PlaceHolder ID="PlaceHolder5" runat="server"></asp:PlaceHolder>
                                    </td>
                                    <td width="10">
                                        &nbsp;
                                    </td>
                                    <td>
                                        &nbsp;<asp:PlaceHolder ID="PlaceHolder6" runat="server"></asp:PlaceHolder>
                                    </td>
                                </tr>
                                <tr>
                                    <td height="20px">
                                    </td>
                                </tr>
                                <tr>
                                    <td align="left">
                                        <asp:Button ID="BackButton" runat="server" CssClass="RedButtonSmall_Back" Height="24px"
                                            Text="Back" BackColor="Transparent" BorderColor="Transparent" BorderWidth="0px"
                                            Style="text-align: right; padding-right: 10px;" OnClick="BackButton_Click" />
                                    </td>
                                </tr>
                            </table>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
</asp:Content>


Here is the Usercontrol:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="GroupTemplateControl.ascx.cs"
    Inherits="MM.MailCampaign.Web.Controls.GroupTemplateControl1" %>
<div>
    <table border="0" cellpadding="0" cellspacing="0" id="tabLetter" width="200px">
        <tr>
            <td class="TitleHeader" align="left">
                <asp:Label ID="Title" runat="server" Text="TitleText"></asp:Label>
            </td>
        </tr>
        k<tr>
            <td>
                <table cellpadding="10" cellspacing="0" class="InnerTable" width="100%">
                    <tr>
                        <td align="center" valign="top">
                            <asp:Image ID="image" runat="server" Width="120px" Height="160px" ImageUrl="~/images/createmailingNEW/AvailableSoon.jpg" />
                        </td>
                    </tr>
                    <tr>
                        <td align="center">
                            <asp:Button ID="SelectButton" runat="server" CssClass="Redbutton" Height="24px" Text="Select template"
                                BackColor="Transparent" BorderColor="Transparent" BorderWidth="0px" Style="text-align: left;
                                padding-left: 7px" />
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
</div>

Using this in the codebehind page_load to place the user controls ready for customising.

            for (int i = 0; i < 6; i++)
            {
               
               Control oControl = LoadControl("~/controls/GroupTemplateControl.ascx");
               Control ph = (Control)FindControl("Placeholder" + i.ToString());
// ph is null here - why?  If I stop here and inspect 'this' I can see placeholder1, placeholder2 etc.

 // alternatively, I tried the indirect route with
//  Control ph = (Control)FindControlRecursive(this,"Placeholder" + i.ToString());

               ph.Controls.Add(oControl);

            }

        public static Control FindControlRecursive(Control container, string name)
        {
            if ((container.ID != null) && (container.ID.Equals(name)))
                return container;

            foreach (Control ctrl in container.Controls)
            {
                Control foundCtrl = FindControlRecursive(ctrl, name);
                if (foundCtrl != null)
                    return foundCtrl;
            }
            return null;
        }


Cheers




0
Comment
Question by:mimpact
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
10 Comments
 
LVL 3

Expert Comment

by:exceter
ID: 35144826
IDs of your Place Holders are CamelCase, that is, capital letters of words - PlaceHolder...
0
 
LVL 14

Expert Comment

by:robasta
ID: 35144843
exceter is right, e.g.    

   Control ph = (Control)FindControl("Placeholder" + i.ToString())

Should be

     Control ph = (Control)FindControl("PlaceHolder" + i.ToString())
0
 

Author Comment

by:mimpact
ID: 35144994
Sorry - Typo in my example - It still returns Null using matching case
0
Increase Agility with Enabled Toolchains

Connect your existing build, deployment, management, monitoring, and collaboration platforms. From Puppet to Chef, HipChat to Slack, ServiceNow to JIRA, Splunk to New Relic and beyond, hand off data between systems to engage the right people.

Connect with xMatters.

 
LVL 14

Expert Comment

by:robasta
ID: 35145085
There are two things:

1. The casing (should be "PlaceHolder"

2. The loop should start on 1, currently, it starts on 0, therefor the first time it looks for PlaceHolder0 (and does not find it), also change 'less than' to 'less than Or Equal to' so that 6 is included.  

Change the loop :
 
for (int i = 0; i < 6; i++)

Open in new window

to start on 1, like so:  
for(int i = 1; i <= 6; i++)

Open in new window

0
 

Author Comment

by:mimpact
ID: 35145106
That's true (i shld start at 1 - should have fixed that before I uploaded the example - but I was getting pretty frustrated by then) - but anyway, when it gets to 1 it should still return a value - but it doesn't.
0
 
LVL 14

Expert Comment

by:robasta
ID: 35146299
i used your HTML markup with the following code and it worked (added my literal control on all six placeholders):
protected void Page_Load(object sender, EventArgs e)
        {
              for (int i = 1; i <= 6; i++)
            {
                
               //Control oControl = LoadControl("~/controls/GroupTemplateControl.ascx");
               Control ph = (Control)FindControl("PlaceHolder" + i.ToString());
// ph is null here - why?  If I stop here and inspect 'this' I can see placeholder1, placeholder2 etc.

 // alternatively, I tried the indirect route with
//  Control ph = (Control)FindControlRecursive(this,"Placeholder" + i.ToString());

               //ph.Controls.Add(oControl);
                  Literal lit = new Literal();
                  lit.Text = "test 123";
               ph.Controls.Add(lit);

            }
        }

Open in new window

0
 

Author Comment

by:mimpact
ID: 35146389
Hmmm.
So it must be something to do with this system

Would the class declaration affect finding controls?
This is the declaration for this page's class

   public partial class SelectTemplate : DealershipPage
    {
        protected void Page_Load(object sender, EventArgs e)
        {
          .....

0
 
LVL 14

Accepted Solution

by:
robasta earned 500 total points
ID: 35146542
my mistake, I initially used your code on a page without a Master page.

Since your page uses a master page, you first need to get the ContentPlaceHolder, then call FindControl on the ContentPlaceHolder like this:
for (int i = 1; i <= 6; i++)
            {
                ContentPlaceHolder BodyContentPlaceHolder = (ContentPlaceHolder)this.Page.Master.FindControl("ContentPlaceHolder1");
                //Control oControl = LoadControl("~/controls/GroupTemplateControl.ascx");
                Control ph = (Control)BodyContentPlaceHolder.FindControl("PlaceHolder" + i.ToString());
                // ph is null here - why?  If I stop here and inspect 'this' I can see placeholder1, placeholder2 etc.

                // alternatively, I tried the indirect route with
                //  Control ph = (Control)FindControlRecursive(this,"Placeholder" + i.ToString());

                //ph.Controls.Add(oControl);
                Literal lit = new Literal();
                lit.Text = "test 123";
                ph.Controls.Add(lit);

            }

Open in new window


0
 

Author Comment

by:mimpact
ID: 35146582
you the MAN!
0
 

Author Closing Comment

by:mimpact
ID: 35146604
My description obscured part of the information needed to provide the answer initially, but once that was clarified, the answer came fast and accurate.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …

717 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question