2010-02-09 9 views
1

Je développe un ensemble de contrôles personnalisés, l'un d'eux est le "parent", tous les autres doivent être ajoutés à l'intérieur d'une propriété ITemplate de ce parent.Asp.Net Personnalisation du contrôle de temps question

Mais dans la page, au moment de la conception, je peux voir, par intellisense, les autres contrôles au niveau de la page, et je peux théoriquement les ajouter partout.

Je veux imiter le comportement du asp: Table et asp: TableRow, vous ne pouvez pas ajouter directement un aspic: TableRow en dehors d'un asp: Table ...

est-il un moyen d'atteindre cet ? Merci beaucoup!

éditer: J'ai partiellement résolu avec la suggestion de KP, mais si vous lisez au commentaire ce n'est pas la "vraie" façon de le faire (je pense). Personne ne sait comment faire cela? :(

Répondre

2

J'ai modifié la réponse entière basée Nous avons ci-dessous deux contrôles - ParentControl et ChildControlParentControl est visible via Intellisense, où ChildControl est seulement visible comme un enfant de ParentControl comme vous le vouliez. li tags et ou tput leur propriété 'text'. Le contrôle parent s'assure que chaque enfant est invité à rendre au cours de son propre événement RenderContents.

Child Control:

using System.ComponentModel; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace TestControls 
{ 
    [ToolboxItem(false), Bindable(false)] 
    public class ChildControl : WebControl 
    { 
     protected override void Render(System.Web.UI.HtmlTextWriter writer) 
     { 
      base.Render(writer); 

      //render the text property as a list item for example's sake 
      writer.RenderBeginTag(HtmlTextWriterTag.Li); 
      writer.Write(this.Text); 
      writer.RenderEndTag(); 
     } 

     [Browsable(true)] 
     public string Text { get; set; } 
    } 
} 

Parent Control:

using System.Collections.Generic; 
using System.ComponentModel; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace TestControls 
{ 
    [ToolboxData("<{0}:ParentControl runat=\"server\"></{0}:ParentControl>")] 
    [DefaultProperty("Children"), ParseChildren(true, "Children")] 
    public class ParentControl : WebControl 
    { 
     private List<ChildControl> _children; 

     protected override void RenderContents(HtmlTextWriter writer) 
     { 
      base.RenderContents(writer); 

      //create a div, and write some sample text 
      writer.RenderBeginTag(HtmlTextWriterTag.Div); 
      writer.Write("Parent Control. Children:"); 

      //create a ul, and ask each child control to render 
      writer.RenderBeginTag(HtmlTextWriterTag.Ul); 

      foreach (ChildControl child in _children) 
      { 
       child.RenderControl(writer); 
      } 

      //close all tags 
      writer.RenderEndTag(); 
      writer.RenderEndTag(); 
     } 

     [PersistenceMode(PersistenceMode.InnerDefaultProperty)] 
     public virtual List<ChildControl> Children 
     { 
      get 
      { 
       if (_children == null) 
        _children = new List<ChildControl>(); 

       return _children; 
      } 
     } 
    } 
} 

Dans mon code, j'enregistré les commandes via l'espace de noms:

<%@ Register TagPrefix="test" Namespace="TestControls" %> 

Et puis ajouté quelques balisage: 01 Dans le balisage ci-dessus, Intellisense détecte le contrôle parent externe, mais ne voit pas le contrôle enfant. Une fois que le curseur se trouve dans le contrôle parent, Intellisense décroche le tag ChildControl comme souhaité.

Le résultat final est la suivante:

Parent Control. Enfants:

* Hello World from Child 1 
* Hello World from Child 2 

De plus, voici un good article on how the whole intellisence creation works, que je suivais pour créer ce qui précède.

J'espère que cela aide. Vous devez toujours gérer le rendu au niveau du contrôle enfant de la manière que vous souhaitez pour vos contrôles spécifiques. Toutefois, ce qui précède vous permet de démarrer et répond au besoin d'un modèle Intellisense fonctionnel.

+0

à mon sous-contrôle J'ai ajouté [ToolboxItem (false)], puis je l'ai exposé comme propriété du contrôle parent avec l'attribut [PersistenceMode (PersistenceMode.InnerProperty)]. Je pense que ce n'est pas la "bonne" façon de le faire, mais à ce moment-là, c'est le seul qui fait l'affaire ... – tanathos

+0

Pourquoi est-ce la façon "incorrecte"? Je crois que vous êtes sur la bonne voie. Un autre exemple utilisant les mêmes attributs: http://www.robertwray.co.uk/blog/2008/02/describing-aspnet-control-properties-declaratively.html –

+0

parce que de cette façon mon contrôle secondaire ne se rend pas automatiquement, c'est une simple propriété de son parent, je dois implémenter une logique de rendu au niveau parent ... Honnêtement, je ne comprends pas comment asp: TableRow et asp: Table fonctionne, j'ai vu leur code dans le réflecteur, mais je n'ai pas trouvé une raison qui rend TableRow invisible en dehors de la table .... – tanathos

0

Je l'ai déjà fait mais je n'ai pas le code disponible Je peux vous dire que je l'ai compris en utilisant Reflector sur le contrôle ASP.NET Datagrid intégré. l'ingénieur la relation entre le "contenu" ("row") et "container" ("grille") .Vous devez organiser les classes ensemble d'une manière très spécifique en utilisant des attributs

Questions connexes