2009-06-29 2 views
6

Добрый день, все,Доступ к управлению содержимым в C# при использовании мастер-страниц

Я строю страницу в ASP.NET и используя мастер-страницы в процессе.

У меня есть имя владельца содержимого «cphBody» на моей странице мастера, в котором будет содержаться тело каждой страницы, для которой эта страница мастера является главной страницей.

На веб-странице ASP.NET у меня есть тег Content (ссылка «cphBody»), который также содержит некоторые элементы управления (кнопки, элементы управления Infragistics и т. Д.), И я хочу получить доступ к этим элементам управления в файле CodeBehind. Однако я не могу сделать это напрямую (this.myControl ...), так как они вложены в тег Content.

Я нашел обходное решение с методом FindControl.

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

Это работает просто отлично. Тем не менее, я подозреваю, что это не очень хороший дизайн. Вы, ребята, знаете более элегантный способ сделать это?

Спасибо!

Guillaume Gervais.

+1

вы пытаетесь доступ к элементам управления из коды страницы по контенту или код мастер-странице позади? – wulimaster

+0

Код CodeBehind. –

+0

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

ответ

4

Рик Стрэхл имеет хорошее объяснение (и пример кода) здесь - http://www.west-wind.com/Weblog/posts/5127.aspx

+0

Спасибо! Это в основном то, что я сделал, поэтому он проверяет мой метод для меня! –

+0

Мне очень не нравится FindControl, это обычно необходимо, когда вы не можете выявить сильное типизированное свойство, и вам нужно прорыть предварительно обработанный вывод. – CRice

1

Я использую этот код для Асесса в файлы рекурсивно:

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

Я стараюсь избегать FindControl, если нет альтернативы, и обычно есть более аккуратный способ.

Как насчет включая путь к вашей главной странице в верхней части детской страницы

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

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

Тогда из вашего мастер-кода страницы позади вы могли бы сделать это свойство вернуть контроль или сделать метод на главной странице получить контроль и т.д.

public Label SomethingLabel 
{ 
    get { return lblSomething; } 
} 
//or 
public string SomethingText 
{ 
    get { return lblSomething.Text; } 
    set { lblSomething.Text = value; } 
} 

Относится к метке на главной странице

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

Использование:

Master.SomethingLabel.Text = "some text"; 
//or 
Master.SomethingText = "some text"; 
+0

Как насчет другого пути? У меня есть «GridView» на моей странице контента, и я хочу иметь возможность обновить его с моего MasterPage. – Si8

+0

Я бы поднял событие с данными о событиях, которые вам нужны с главной страницы, и подписаться на нее со своей страницей. Master.SomeEvent + = SomeHandler; – CRice

3

Ничего делать разные. Просто напишите этот код на дочерней странице, чтобы получить доступ к управлению меткой главной страницы.

Label lblMessage = new Label(); 
lblMessage = (Label)Master.FindControl("lblTest"); 
lblMessage.Text = DropDownList1.SelectedItem.Text; 
1

Привет просто думал, что я хотел бы поделиться моим решением, нашел, что это работает для доступа к «Control», которая находится внутри < осины: Панельный>, который находится на «ContentPage», но из C# код из «MasterPage». Надеюсь, это поможет некоторым.

  1. < добавить жерех: Панель управления> с ID = "PanelWithLabel" и RunAt = "сервер" к вашему ContentPage.

  2. внутри панели, добавьте < asp: Ярлык> управление с ID = "MyLabel".

  3. напишите (или скопируйте/вставьте ниже) функцию в свой код MasterPage следующим образом: (это обеспечивает доступ к элементу управления ярлыками внутри панели, которые находятся на ContentPage, из кода главной страницы и изменения его текст в том, что из TextBox на главной странице :)

    protected void onButton1_click(object sender, EventArgs e) 
    { 
    // find a Panel on Content Page and access its controls (Labels, TextBoxes, etc.) from my master page code behind // 
    System.Web.UI.WebControls.Panel pnl1; 
    pnl1 = (System.Web.UI.WebControls.Panel)MainContent.FindControl("PanelWithLabel"); 
    if (pnl1 != null) 
    { 
        System.Web.UI.WebControls.Label lbl = (System.Web.UI.WebControls.Label)pnl1.FindControl("MyLabel"); 
        lbl.Text = MyMasterPageTextBox.Text; 
    } 
    }