Using FindControl() to find control
Asked Answered
Q

5

13

I have a Literal control that I am trying to locate so I can insert text into it. I have a Master page that contains several content placeholders.

<asp:Content ID="Content7" ContentPlaceHolderID="MainLinks" runat="server">
    <h3>Project Navigation</h3>
<ul class="rightColBoxNav">
<asp:Literal ID="litNavLinks" runat="server" />
</ul>
</asp:Content>

I keep getting "Object reference not set to an instance of an object." How do I locate this object so I can find and update it?

I have tried:

((Literal)Page.FindControl("litNavLinks")).Text = sb.ToString();
((Literal)Page.Page.FindControl("litNavLinks")).Text = sb.ToString();
((Literal)Page.FindControl("Content7").FindControl("litNavLinks")).Text = sb.ToString();

to no avail. How do I determine the location?

Quiddity answered 16/9, 2010 at 21:34 Comment(3)
Haven't tried it, but can you use litNavLinks.Text = sb.ToString()?Society
Seeing that with Darin's answer. I'll have to try it in the morning. I did not try it and I bet it'll work. I feel stupid if that is the case. I feel stupid now thinking that is right.Quiddity
Sometimes it's the simple stuff that trips us up.Society
S
12

From within the masterpage:

var literal = (Literal)FindControl("MainLinks").FindControl("litNavLinks");
literal.Text = sb.ToString();

From within the view:

litNavLinks.Text = sb.ToString();
Snapper answered 16/9, 2010 at 21:40 Comment(0)
I
1

I would try a different approach.

How about using a user control and exposing the relevant properties to get or set the text value.

The property would be accessing the literal control. However, the page calling the property wouldn't be any wiser.

Remember we live in a OO world.

Indira answered 16/9, 2010 at 21:48 Comment(0)
T
1

I think you have to do this, but I don't have my code to double-check right now:

Page.Master.FindControl("MainLinks").FindControl("litNavLinks");
Tetraploid answered 16/9, 2010 at 21:50 Comment(0)
S
1

The ASP ContentPlaceHolder control is a "naming container" (it implements the INamingContainer interface). The Control.FindControls method only searches within the current naming container for a control with the ID that you specify.

I've occassionally included a utility function that accepts a "/" delimited string to arbitrarily navigate through the naming containers on a page. Something like the following implementation. (Note: I have not tried to compile or test this code)

    public static Control FindControlByPath(this Control start, string controlPath)
    {
        if(controlPath == null)
            throw new ArgumentNullException("controlPath");

        string[] controlIds = controlPath.split('/');

        Control current = start;
        if(controlIds[0] == "") // in case the control path starts with "/"
            current = start.Page; // in that case, start at the top

        for(int i=0; i<controlIds.Length; i++)
        {
            switch(controlIds[i])
            {
                case "":
                    // TODO: handle syntax such as "<controlId>//<controlId>", if desired
                    break;

                case ".":
                    // do nothing, stay on the current control
                    break;

                case "..":
                    // navigate up to the next naming container
                    current = current.Parent;
                    if(current == null)
                        throw new ArgumentOutOfRangeException("No parent naming container exists.", "controlPath");

                    while(!(current is INamingContainer))
                    {
                        current = current.Parent;
                        if(current == null)
                            throw new ArgumentOutOfRangeException("No parent naming container exists.", "controlPath");
                    }                       
                    break;

                default:
                    current = current.FindControl(controlIds[i]);
                    break;
            }
        }

        return current;
    }

So, in your case you should be able to do the following:

<some control>.FindControlByPath("/MainLinks/litNavLinks").Text = sb.ToString();

or

Page.FindControlByPath("MainLinks/litNavLinks").Text = sb.ToString();
Selina answered 16/9, 2010 at 21:57 Comment(0)
B
-2
Literal tbx = this.Controls.Find("Literal1", true).FirstOrDefault() as Literal;
Bing answered 19/1, 2016 at 11:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.