2009-05-31 6 views
0

Je construis un menu pop-out, et le client veut qu'il soit capable de sortir en continu selon une hiérarchie.Comment puis-je empiler un nombre inconnu de répéteurs ASP.NET?

Par exemple, le premier volet est une liste d'options. Quand ils sont survolés, un autre volet devrait apparaître à côté du prochain niveau d'options, et ainsi de suite jusqu'à ce que le dernier niveau d'options soit atteint.

Je peux gérer tout le javascript et d'autres choses, mais je ne peux pas penser à un moyen d'intégrer continuellement des répéteurs à l'intérieur des répéteurs. Je sais que je pourrais le faire une fois en mettant un répéteur à l'intérieur d'un autre, mais alors je n'aurais que deux couches.

Je dois être en mesure d'intégrer en continu des répéteurs pour chaque couche d'options, ou d'y parvenir avec une technique similaire en utilisant un contrôle différent.

Toute aide est super, merci!

Répondre

0

Vous ne serez pas en mesure de construire cela en balisage. Vous devrez ajouter les contrôles dynamiquement dans votre code en construisant le répéteur pour chaque niveau et en l'ajoutant au modèle du répéteur précédent. Il faudra une publication complète pour chaque option sélectionnée, car le répéteur imbriqué pourrait avoir une profondeur différente selon l'option choisie.

Vous feriez peut-être mieux de faire cela tout le côté client, en utilisant AJAX et javascript. Lorsqu'une option est choisie, déclenchez une requête AJAX pour voir si cette option a des sous-options. Si c'est le cas (renvoyez-les), créez dynamiquement le nouveau contrôle d'options à l'aide de javascript et ajoutez-le à la page. Lorsqu'une option différente est choisie, vous supprimez les éléments du DOM contenant les sous-options d'options précédemment choisies.

+0

Merci, c'est utile :) –

0

Si vous pouvez obtenir votre menu sous la forme d'une liste d'objets MenuItem, dont chacun a une liste (parfois vide) de sous-éléments (et je veux vraiment dire un List<MenuItem> ici ... nous allons utiliser cette collection en tant que source de données pour un sous-répéteur, donc il doit implémenter IEnumerable<T>) comme une propriété MenuItem.SubItems, vous pouvez probablement faire usage d'un UserControl qui boucle un niveau de menu, et appelle lui-même pour le prochain.

Dans le UserControl vous auriez quelque chose comme ceci:

<li><a href='<%= this.MenuItem.Url %>'><%= this.MenuItem.LinkText %></a></li> 
<asp:Repeater ID="UCRepeater" runat="server"> 
    <HeaderTemplate> 
     <ul> 
    <ItemTemplate> 
     <menu:MenuItem ID="MenuItemUC" runat="server" /> 
    </ItemTemplate> 
    <FooterTemplate> 
     </ul> 
    </FooterTemplate> 
</asp:Repeater> 

Le UserControl dans le ItemTemplate est le même, donc pour chaque modèle d'élément sera rendu la même chose.

est en dessous du code derrière pour ce contrôle utilisateur, ce qui est là que la magie se produit:

public partial class MenuItemUserControl : UserControl 
{ 
    // A property we'll use as the data source 
    public MenuItem MenuItem { get; set; } 

    protected void Page_Load(object sender, EventArgs e) 
    { 
     // If the current menu item has sub items, we bind the repeater to them 
     // And by the way, there is no use doing this on every postback. First 
     // page load is good enough... 
     if(!Page.IsPostBack) { 
     { 
      if(MenuItem.SubItems.Count > 0) 
      { 
       UCRepeater.DataSource = MenuItem.SubItems; 
       UCRepeater.DataBind(); 
      } 
     } 
    } 
    protected void UCRepeater_OnItemDataBound(object sender, 
       RepeaterDataBoundEventArgs e) 
    { 
     // Every time an Item is bound to the repeater, we take the current 
     // item which will be contained in e.DataItem, and set it as the 
     // MenuItem on the UserControl 

     // We only want to do this for the <ItemTemplate> and 
     // <AlternatingItemTemplate> 
     if(e.Item.ItemType == ListItemType.Item || 
      e.Item.ItemType == ListItemType.AlternatingItem) 
     { 
      var uc = (MenuItemUserControl)e.Item.FindControl("MenuItemUC"); 
      if(uc != null) 
      { 
       // This is the magic. Abrakadabra! 
       uc.MenuItem = (MenuItem)e.DataItem; 
      } 
     } 

    } 
} 

Ainsi, afin d'obtenir ce travail, la seule chose qui manque est vraiment une belle façon d'obtenir votre données sous la forme d'une liste hiérarchique de MenuItem s. Cela je laisse à votre couche d'accès de données (et il serait bon marché facile utilisant LINQ à SQL ou Entity Framework ...;))

DISCLAIMER: Ce code est fourni tel quel, et je l'ai écrit du haut de ma tête. Je ne l'ai pas testé, mais je pense que cela fonctionnera - et si ce n'est pas le cas, cela pourrait au moins vous donner une idée de la façon de résoudre le problème. Si vous avez des problèmes, s'il vous plaît les poster dans les commentaires et je vais essayer de vous aider - mais il n'y a aucune promesse de succès ici. Juste une volonté d'aider! =)

Questions connexes