2009-05-31 12 views
0

Ich baue ein Pop-Out-Menü auf, und der Client möchte, dass es basierend auf einer Hierarchie fortlaufend verfügbar ist.Wie kann ich eine unbekannte Anzahl von ASP.NET Repeatern stapeln?

Zum Beispiel ist der erste Bereich eine Liste von Optionen. Wenn sie sich über dem Fenster befinden, sollte neben der nächsten Ebene der Optionen ein weiteres Fenster eingeblendet werden, bis die letzte Ebene der Optionen erreicht ist.

Ich kann das ganze Javascript und andere Sachen handhaben, aber ich kann mir keinen Weg vorstellen, Repeater in Repeater einzubetten. Ich weiß, ich könnte es einmal tun, indem ich einen Repeater in einen anderen stecke, aber dann hätte ich nur zwei Schichten.

Ich muss in der Lage sein, Wiederholer für jede Schicht von Optionen kontinuierlich einzubetten, oder erreichen Sie dies mit einer ähnlichen Technik, die eine andere Kontrolle verwendet.

Jede Hilfe ist großartig, danke!

Antwort

0

Sie können dies nicht in mark up erstellen. Sie müssen die Steuerelemente dynamisch in Ihrem Code hinzufügen, indem Sie den Repeater für jede Ebene erstellen und zur vorherigen Repeater-Vorlage hinzufügen. Für jede ausgewählte Option ist ein vollständiger Postback erforderlich, da der verschachtelte Repeater abhängig von der gewählten Option möglicherweise unterschiedliche Tiefe aufweisen kann.

Sie können es jedoch besser tun dies alle Client-Seite, obwohl mit AJAX und Javascript. Wenn eine Option ausgewählt ist, feuern Sie eine AJAX-Anfrage ab, um zu sehen, ob diese Option Unteroptionen hat. Wenn dies der Fall ist (Rückgabewerte), erstellen Sie das neue Optionen-Steuerelement dynamisch mithilfe von JavaScript und fügen Sie es der Seite hinzu. Wenn eine andere Option ausgewählt wird, entfernen Sie die Elemente aus dem DOM, die die zuvor ausgewählten Optionen-Unteroptionen enthalten.

+0

Danke, das ist hilfreich :) –

0

Wenn Sie Ihr Menü in Form einer Liste von MenuItem Objekte, von denen jede eine (manchmal leere) Liste von Unterelementen (und ich meine wirklich eine List<MenuItem> hier ... Wir werden verwenden Diese Sammlung als Datenquelle für einen Sub-Repeater, so dass es IEnumerable<T> implementieren muss) als eine Eigenschaft MenuItem.SubItems, könnten Sie wahrscheinlich eine UserControl verwenden, die eine Menüebene loops, und ruft sich für die nächste.

In der UserControl Sie etwas davon haben würde:

<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> 

Die UserControl im ItemTemplate ist die gleiche, so dass für jedes Element Vorlage wird die gleiche Sache gemacht werden.

Unten ist der Code-behind für diesen Benutzer die Kontrolle, und das ist, wo die Magie passiert:

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; 
      } 
     } 

    } 
} 

So zu arbeiten, um dies zu erreichen, fehlt das einzige, was wirklich eine gute Möglichkeit, Ihre zu bekommen Daten aus einer hierarchischen Liste von MenuItem s. Dies überlasse ich Ihrer Datenzugriffsebene (und es wäre billig, einfach LINQ to SQL oder Entity Framework zu verwenden ...)

DISCLAIMER: Dieser Code wird zur Verfügung gestellt, wie es ist, und ich schrieb es von der Spitze von meinem Kopf. Ich habe es nicht getestet, aber ich denke, es wird funktionieren - und wenn es nicht funktioniert, könnte es Ihnen zumindest eine Idee geben, wie Sie das Problem lösen können. Wenn du Probleme hast, poste sie bitte in Kommentaren und ich werde versuchen zu helfen - aber es gibt keine Erfolgsversprechen hier. Nur eine Bereitschaft zu helfen! =)

Verwandte Themen