2009-10-21 6 views
2

J'écris un petit contrôle personnalisé ASP.Net héritant de CompositeControl. Le contrôle est juste un panneau contenant deux sous-panneaux avec une étiquette dans chaque sous-panneau. Une fois rendu, je vois dans la source HTML que le premier contrôle enfant de mon contrôle personnalisé obtient deux attributs id - le premier étant l'identifiant du contrôle personnalisé lui-même et le second étant la propriété ID que j'attribue au premier contrôle enfant. Pourquoi cela arrive-t-il?Pourquoi mon contrôle personnalisé ASP.Net rend-il deux attributs id sur mon premier contrôle enfant?

code:

[ToolboxData("<{0}:MessageBox runat=server></{0}:MessageBox>")] 
public class MessageBox : CompositeControl { 

    private Panel _MessageHeaderContainer = null; 
    private Label _MessageHeaderLabel = null; 
    private Panel _MessageDetailsContainer = null; 
    private Label _MessageDetailsLabel = null; 

    protected override HtmlTextWriterTag TagKey { 
     get { 
      return HtmlTextWriterTag.Div; 
     } 
    } 

    protected override void CreateChildControls() { 

     // Message header area. 
     _MessageHeaderContainer = new Panel(); 
     _MessageHeaderContainer.ID = "HeaderContainer"; 
     _MessageHeaderContainer.CssClass = "__MessageBox_Container"; 
     this.Controls.Add(_MessageHeaderContainer); 

     // Message header text. 
     _MessageHeaderLabel = new Label(); 
     _MessageHeaderLabel.ID = "HeaderLabel"; 
     _MessageHeaderLabel.Text = "[ Header ]"; 
     _MessageHeaderContainer.Controls.Add(_MessageHeaderLabel); 

     // Message details area. 
     _MessageDetailsContainer = new Panel(); 
     _MessageDetailsContainer.ID = "DetailsContainer"; 
     this.Controls.Add(_MessageDetailsContainer); 

     // Message details text. 
     _MessageDetailsLabel = new Label(); 
     _MessageDetailsLabel.ID = "DetailsLabel"; 
     _MessageDetailsLabel.Text = "[ Details ]"; 
     _MessageDetailsContainer.Controls.Add(_MessageDetailsLabel); 

    } 

    protected override void RenderContents(HtmlTextWriter output) { 
     AddAttributesToRender(output); 

     // Render the box. 
     _MessageHeaderContainer.RenderControl(output); 
     _MessageDetailsContainer.RenderControl(output); 
    } 
} 

Utilisation en page ASPX:

<cc:MessageBox ID="ctlMessageBox" runat="server" /> 

sortie HTML:

<div id="ctl00_ctl00_ctlMessageBox"> 
    <div id="ctl00_ctl00_ctlMessageBox" id="ctl00_ctl00_ctlMessageBox_HeaderContainer" class="__MessageBox_Container"> 
     <span id="ctl00_ctl00_ctlMessageBox_HeaderLabel">[ Header ]</span> 
    </div><div id="ctl00_ctl00_ctlMessageBox_DetailsContainer"> 
     <span id="ctl00_ctl00_ctlMessageBox_DetailsLabel">[ Details ]</span> 
    </div> 
</div> 
+0

Il semble aussi que toute propriété que je cède le contrôle lui-même (à savoir, this.CssClass = « xxxx ») est attribué, à la plus externe de contrôle, généré automatiquement div tag ainsi que rendu la balise div du premier contrôle enfant. –

+0

Retrait de la ligne AddAttributesToRender (sortie) de l'arrêt de la fonction de rendu en ajoutant tous les attributs de l'étiquette de la racine à la première enfant. Je ne suis pas sûr de ce que le point de la fonction AddAttributesToRender est ... quelqu'un peut m'éclairer pour savoir pourquoi j'appellerais cette fonction? –

+0

Vous l'appelleriez si vous vouliez plus de contrôle sur la façon dont vos rendus personnalisés de contrôle. Il ajoute les attributs qui doivent être affectés au contrôle personnalisé (style, etc., du balisage ASPX et d'autres sources) à la prochaine balise qui est rendu. Vous n'en avez pas besoin car vous laissez ASP.NET s'occuper du rendu. Si vous substituez la méthode Render (comme mon exemple), vous en aurez besoin. –

Répondre

4

Vous pouvez corriger cela en supprimant la méthode RenderContents entièrement - ne remplace pas avec quoi que ce soit. Par défaut, les contrôles composites affichent tous leurs contrôles enfants. Si vous faites cela, votre contrôle produit balisage propre:

<div id="test"> 
    <div id="test_HeaderContainer" class="__MessageBox_Container"> 
    <span id="test_HeaderLabel">[ Header ]</span> 
    </div> 
    <div id="test_DetailsContainer"> 
    <span id="test_DetailsLabel">[ Details ]</span> 
    </div> 
</div> 

Comme vous l'avez noté, la méthode AddAttributesToRender est le coupable - c'est une méthode pratique rend tous les attributs du contrôle de niveau supérieur (si le contexte actuel est le contrôle de premier niveau ou non). La seule raison que vous appelleriez ceci est si vous preniez vous-même le contrôle total du processus de rendu et que vous vouliez rendre tous les attributs du contrôle de niveau supérieur dans une seule instruction.

+0

go 1 -.. Merci très utile!. –

-1

Ceci est l'ID ASP.NET affecte le contrôle personnalisé dans son ensemble. Si vous enroulez votre Contrôle Personnalisé dans une Div ou une Span (dans le code de Contrôle Personnalisé lui-même, pas dans le balisage), l'ID sera assigné à cela au lieu de votre premier "contrôle" interne.

Quelque chose comme ceci:

protected override void Render(HtmlTextWriter writer) 
{ 
    AddAttributesToRender(writer); 

    //must render tag or first inner control will get two IDs 
    writer.RenderBeginTag(HtmlTextWriterTag.Span); 

    //render child controls here... 

    writer.RenderEndTag(); 
} 
+0

Je l'ai fait en ajoutant output.RenderBeginTag (HtmlTextWriterTag.Div) comme la première ligne sous le commentaire « rendu la case » (et j'ai ajouté le output.RenderEndTag() appropriée après avoir rendu les contrôles enfants. Maintenant, la sortie HTML comprend une englobante balise div avec un id en double comme propre « root » div tag contrôle personnalisé Fondamentalement, j'ai

< child control stuff />
J'ai toujours id de contrôle en double de dans la sortie rendue -... pas de bons –

+1

Essayez impérieuses « Render », et non « RenderContents » aussi ., essayez de supprimer HtmlTextWriterTag TagKey –

+0

J'ai essayé de rendre une première durée Pas – sq33G

Questions connexes