2010-08-31 4 views
1

Fondamentalement, j'ai un contrôle basé sur un modèle personnalisé avec une classe de conteneur de données personnalisée. Lorsqu'un développeur ajoute une instance de mon contrôle à une page, ils peuvent définir les contrôles dans le LayoutTemplate comme ils l'entendent, comme suit:Contrôle personnalisé basé sur un modèle ASP.NET - Existe-t-il un moyen de modifier la destination des données de base de données?

<ml:MyControl id="MyControl1" runat="server"> 
     <LayoutTemplate> 
      <span><%#Container.ErrorMessage%></span> 
     </LayoutTemplate> 
    </ml:MyControl> 

Cet exemple rend sur la page comme ceci:

<span id="MyControl1"><span> 
      <span>ml_errormessage</span> 

     </span></span> 

Je voudrais que mon contrôle déplace automatiquement le "ml_errormessage" (contenu de datation de Container.ErrorMessage - jeton codé en dur dans la propriété) pour qu'il devienne une classe de son élément conteneur afin de permettre à jQuery d'utiliser plus facilement un sélecteur pour trouver l'élément et insérez dynamiquement le côté client du message d'erreur. Plus important encore, je voudrais qu'il soit déplacé de sorte que le nom de classe ne soit pas remplacé par le contenu et que jQuery puisse le trouver autant de fois qu'il le faut pendant le cycle de vie de la page. En d'autres termes, je voudrais que la sortie ressemble à ceci sans le développeur de changer le modèle d'entrée ou de recours à l'aide de contrôles personnalisés dans le modèle:

<span id="MyControl1"><span> 
      <span class="ml_errormessage"></span> 

     </span></span> 

Je voudrais passer la valeur à l'aide de la collection de contrôles plutôt que avoir recours à l'analyse syntaxique de la sortie, si possible. Cependant, quand j'interroge la collection dans une substitution de OnPreRender, le contrôle dans le modèle ressemble à ceci dans le débogueur:

{System.Web.UI.DataBoundLiteralControl} 
System.Web.UI.DataBoundLiteralControl: {System.Web.UI.DataBoundLiteralControl} 
AppRelativeTemplateSourceDirectory: "~/" 
BindingContainer: {MyControls.MyControlData} 
ClientID: "MyControl1_ctl01_ctl00" 
Controls: {System.Web.UI.EmptyControlCollection} 
EnableTheming: True 
EnableViewState: True 
ID: "ctl00" 
NamingContainer: {MyControls.MyControlData} 
Page: {ASP.default_aspx} 
Parent: {MyControls.MyControlData} 
Site: Nothing 
SkinID: "" 
TemplateControl: {ASP.default_aspx} 
TemplateSourceDirectory: "/MyControls" 
UniqueID: "MyControl1$ctl01$ctl00" 
Visible: True 

Comme vous pouvez le voir la valeur « ml_errormessage » est introuvable. Lors de l'analyse de l'événement DataBind de la classe Control à l'aide de Reflector, je vois qu'il délègue le comportement de liaison à chaque contrôle. En d'autres termes, chaque contrôle gère sa propre liaison de données. Cependant, comme je n'ai aucun moyen de savoir à l'avance quels types de contrôle seront dans le modèle, comment ce changement peut-il être effectué?

Note: une alternative acceptable serait d'ajouter un nouveau HtmlGenericControl (span) à l'endroit exact où le "ml_errormessage" est et de l'ajouter en tant que classe à ce nouveau contrôle. Sur une note de côté, y a-t-il un moyen facile d'indenter la sortie du contrôle pour faciliter la lecture pendant le débogage?

Répondre

1

Seulement quelques secondes après avoir posté ceci, j'ai pensé à une solution facile ... simplement le code dur "<span class=""ml_errormessage""></span>" comme le résultat de ma propriété de conteneur ErrorMessage. Bien sûr, il ajoute un élément supplémentaire inutile <span>, mais il est également plus sûr si le développeur final décide de mettre des éléments supplémentaires avec la valeur de la base de données.

Questions connexes