J'ai modifié la réponse entière basée Nous avons ci-dessous deux contrôles - ParentControl
et ChildControl
ParentControl
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.
à 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
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 –
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