2009-06-29 5 views
6

Bonjour à tous,Accéder à un contrôle de contenu en C# lors de l'utilisation des pages maîtres

Je construis une page ASP.NET, et l'utilisation des pages maître dans le processus.

J'ai un nom de détenteur de contenu de contenu "cphBody" dans ma page maître, qui contiendra le corps de chaque page pour laquelle cette page maître est la page maître.

Sur la page Web ASP.NET, j'ai un tag Content (référençant "cphBody") qui contient également des contrôles (boutons, contrôles Infragistics, etc.), et je souhaite accéder à ces contrôles dans le fichier CodeBehind. Cependant, je ne peux pas le faire directement (this.myControl ...), car ils sont imbriqués dans la balise Content.

J'ai trouvé une solution de contournement avec la méthode FindControl.

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

Cela fonctionne très bien. Cependant, je soupçonne que ce n'est pas un très bon design. Est-ce que vous connaissez une façon plus élégante de le faire?

Merci!

Guillaume Gervais.

+1

vous essayez d'accéder aux commandes de la page de la codebehind de contenu, ou le code de la page principale derrière? – wulimaster

+0

CodeBehind de la page Contenu. –

+0

C'est bizarre. Vous devriez être en mesure d'accéder directement à vos contrôles depuis le code-behind de votre page de contenu, à moins qu'ils ne soient créés et ajoutés dynamiquement. –

Répondre

4

Rick Strahl a une bonne explication (et exemple de code) ici - http://www.west-wind.com/Weblog/posts/5127.aspx

+0

Merci beaucoup! C'est essentiellement ce que j'ai fait, donc ça valide ma méthode pour moi! –

+0

Je n'aime vraiment pas FindControl, il n'est normalement nécessaire que lorsque vous ne pouvez pas exposer une propriété fortement typée et que vous devez explorer la sortie pré-rendue. – CRice

1

-je utiliser ce code pour acess aux fichiers récursive:

/// <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

j'essayer d'éviter FindControl à moins qu'il n'y a pas d'alternative, et il y a habituellement un moyen plus propre.

Que diriez-vous, y compris le chemin vers votre page principale en haut de votre page enfant

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

qui vous permettra de coder appeler directement à partir de votre code de la page principale derrière.

Ensuite, à partir de votre code de la page principale derrière vous pourriez faire un bien retourner votre commande, ou faire une méthode sur la page principale obtenir votre contrôle, etc.

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

Fait référence à une étiquette sur la page principale

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

Utilisation:

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

Qu'en est-il de l'inverse? J'ai un 'GridView' dans ma page de contenu et je veux être en mesure de mettre à jour à partir de mon MasterPage. – Si8

+0

Je lève un événement avec les données d'événement dont vous avez besoin à partir de la page maître et vous y abonnez avec votre page. Master.SomeEvent + = SomeHandler; – CRice

3

Rien à faire différent. Il suffit d'écrire ce code sur la page enfant pour accéder au contrôle d'étiquette de la page maître.

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

Salut juste pensé que je partage ma solution, a trouvé cela fonctionne pour accéder à un « contrôle » qui se trouve dans une < asp: Panel> qui est sur un « ContentPage », mais à partir de C# code-behind de la 'MasterPage'. J'espère que ça aide certains.

  1. ajouter un < asp: Panel> avec un ID = "PanelWithLabel" et runat = "server" à votre ContentPage.

  2. à l'intérieur du Panel, ajoutez un < asp: Label> control avec ID = "MyLabel". Écrire (ou copier/coller ci-dessous) une fonction dans votre MasterPage Code-behind comme suit: (ceci accède au contrôle d'étiquette, à l'intérieur du Panel, qui sont tous les deux sur le ContentPage, à partir de la page Master code-behind et les changements que son texte soit celle d'une zone de texte sur la page principale :)

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