Использование FindControl () для поиска элемента управления - PullRequest
13 голосов
/ 17 сентября 2010

У меня есть Literal элемент управления, который я пытаюсь найти, чтобы я мог вставить в него текст. У меня есть главная страница, которая содержит несколько заполнителей контента.

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

Я продолжаю получать «Ссылка на объект не установлена ​​на экземпляр объекта». Как мне найти этот объект, чтобы я мог найти и обновить его?

Я пробовал:

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

безрезультатно. Как определить местоположение?

Ответы [ 5 ]

12 голосов
/ 17 сентября 2010

Изнутри главной страницы:

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

Из представления:

litNavLinks.Text = sb.ToString();
1 голос
/ 17 сентября 2010

Элемент управления ASP ContentPlaceHolder является «контейнером именования» (он реализует интерфейс INamingContainer). Control.FindControls метод ищет только в текущем контейнере именования элемент управления с указанным вами идентификатором.

Иногда я включал служебную функцию, которая принимает строку с разделителями "/"произвольно перемещаться по контейнерам именования на странице.Что-то вроде следующей реализации.(Примечание: я не пытался скомпилировать или протестировать этот код)

    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;
    }

Итак, в вашем случае вы сможете сделать следующее:

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

или

Page.FindControlByPath("MainLinks/litNavLinks").Text = sb.ToString();
1 голос
/ 17 сентября 2010

Я думаю, вы должны это сделать, но у меня нет моего кода, чтобы перепроверить прямо сейчас:

Page.Master.FindControl("MainLinks").FindControl("litNavLinks");
1 голос
/ 17 сентября 2010

Я бы попробовал другой подход.

Как насчет использования пользовательского элемента управления и предоставления соответствующих свойств для получения или установки текстового значения.

Свойство будет обращаться к буквальному элементу управления.Однако страница, призывающая свойство, не будет мудрее.

Помните, что мы живем в мире ОО.

0 голосов
/ 19 января 2016
Literal tbx = this.Controls.Find("Literal1", true).FirstOrDefault() as Literal;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...