2010-09-16 3 views
9

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

<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(); 

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

+1

Не пробовал, но вы можете использовать litNavLinks.Text = sb.ToString()? –

+0

Увидев это с ответом Дарина. Я должен буду попробовать это утром. Я не пробовал и держу пари, что это сработает. Я чувствую себя глупо, если это так. Я чувствую себя глупо, думая, что это правильно. –

+0

Иногда это простой материал, который нас заводит. –

ответ

10

Изнутри Masterpage:

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

Изнутри зрения:

litNavLinks.Text = sb.ToString(); 
+0

Как я уже говорил выше. Теперь я чувствую себя глупо. Может быть, мне нужно больше спать по ночам ... –

1

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

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

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

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

1

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

Page.Master.FindControl("MainLinks").FindControl("litNavLinks"); 
1

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

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

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
Literal tbx = this.Controls.Find("Literal1", true).FirstOrDefault() as Literal;