2009-10-30 18 views
1

J'ai un tas d'occurrences de ce type de code standard dans mon projet ASP.NET.ASP.NET: Contrôle utilisateur avec accès aux contrôles qu'il enveloppe

<div class="inputfield"> 
    <div class="tl"> 
    <span class="tr"><!-- --></span> 
    <span class="ll"><!-- --></span> 
    <div class="lr"> 
     <div class="cntnt"> 
     <asp:TextBox .../> 
     </div> 
    </div> 
    </div> 
</div> 

Comme vous avez pu le deviner, tout cet extrait est pur passe-partout sauf pour le champ de texte le plus intérieur.

Quelle est la meilleure façon d'éviter une telle routine dans ASP.NET? Par exemple Django Je voudrais faire une balise personnalisée pour elle, en tant que tel:

{% boiler %} 
<input ... /> 
{% endboiler %} 

Je pensais que peut-être que je peux créer un contrôle utilisateur, mais tous les tutoriels sur les contrôles utilisateur ASP.NET que j'ai trouvé sont très simplistes et "fermeture automatique", c'est-à-dire qu'ils ne sont pas au courant du contenu de l'étiquette. Je besoin de quelque chose le long des lignes de:

<Hello:MyControl> 
    <asp:TextBox .../> 
</Hello> 

Ma question est la suivante: quelle est la meilleure façon d'éviter le passe-partout?

Répondre

2

Vous pouvez utiliser une propriété ITemplate. Ainsi, vous pouvez injecter du contenu différent dans différentes situations.

[PersistChildren(false), ParseChildren(true, "ContentTemplate")] 
public partial class WebUserControl1 : System.Web.UI.UserControl 
{ 

    [System.ComponentModel.Browsable(false), System.Web.UI.PersistenceMode(PersistenceMode.InnerProperty)] 
    public ITemplate ContentTemplate { get; set; } 

    protected override void CreateChildControls() 
    { 
     if (this.ContentTemplate != null) 
      this.ContentTemplate.InstantiateIn(this); 

     base.CreateChildControls(); 
    } 
} 
+0

Je suis désolé, mais je ne comprends vraiment pas comment utiliser cet extrait de code. À quoi ressemble le fichier .ascx dans ce cas? –

+0

Je pense que je comprends maintenant, mais une question demeure ... Et si je ne veux pas utiliser ContentTemplate ou quelque chose comme ça? –

+0

Pourquoi ne le voulez-vous pas? –

0

Placez l'asp: TextBox dans votre contrôle utilisateur, avec les autres balises html. Fournir des propriétés sur votre contrôle utilisateur qui correspondent aux propriétés de la zone de texte, de sorte que vous feriez quelque chose comme ceci:

<Hello:MyControl ID="myControl" runat="server" Width="300px" MaxLength="30" /> 

puis la largeur et les propriétés de MAXLENGTH seraient tout simplement faire transférer à la zone de texte interne.

Vous pouvez également fournir un accès à la zone de texte à partir du contrôle usercontrol et définir toutes les propriétés dans le code derrière.

+0

Cela ne suffit pas, car il devrait être possible de mettre n'importe quoi dans le contrôle, pas seulement les zones de texte. –

+0

Ah - désolé j'ai raté cette partie de la question. –

+0

Je me rends compte maintenant que j'aurais dû être plus clair sur cette partie! :) –

0

Créer une classe comme ceci:

[PersistChildren(false), ParseChildren(true, "ContentTemplate")] 
public class CustomContent:WebControl 
{ 
    [System.ComponentModel.Browsable(false), System.Web.UI.PersistenceMode(PersistenceMode.InnerDefaultProperty)] 
    public ITemplate ContentTemplate { get; set; } 

    private PlaceHolder m_placeHolder; 
    protected override void CreateChildControls() 
    { 
     m_placeHolder = new PlaceHolder(); 

     if (this.ContentTemplate != null) 
      this.ContentTemplate.InstantiateIn(m_placeHolder); 

     Controls.Add(m_placeHolder); 
    } 

    protected override void RenderContents(HtmlTextWriter writer) 
    { 
     writer.Write(@"<div class=""inputfield""> 
<div class=""tl""> 
<span class=""tr""><!-- --></span> 
<span class=""ll""><!-- --></span> 
<div class=""lr""> 
    <div class=""cntnt""> 
"); 
     base.RenderContents(writer); 

     writer.Write(@"  </div> 
</div> 
</div> 
</div> 
"); 
    } 

} 

Cette classe n'est pas un "contrôle de l'utilisateur", il est un "Control Server". Vous pouvez faire la même chose avec un contrôle utilisateur, mais vous aurez des problèmes avec le concepteur. Cela fonctionnera dans le concepteur. Et vous pouvez mettre le balisage comme celui-ci dans votre ASPX:

<uc1:CustomContent runat="server" ID="content"> 
     <asp:textbox runat="server"></asp:textbox> 
    </uc1:CustomContent> 

ne pas oublier la déclaration de la page Inscription en haut de la ASPX

<%@ Register tagprefix="uc1" Assembly="Assembly where CustomContent is" Namespace="namespace where CustomContent is" %> 

Vous pouvez mettre tout ce que vous voulez à l'intérieur du UC1: Les balises CustomContent et il rendra ce HTML standard autour de lui. Si vous êtes curieux de savoir comment fonctionne ITemplate, il ya beaucoup d'articles sur msdn, etc.