Share via


Geschachtelte Datenwebsteuerelemente (C#)

von Scott Mitchell

PDF herunterladen

In diesem Tutorial erfahren Sie, wie Sie einen Repeater verwenden, der in einem anderen Repeater geschachtelt ist. Die Beispiele veranschaulichen, wie sie den inneren Repeater sowohl deklarativ als auch programmgesteuert auffüllen.

Einführung

Neben statischer HTML- und Datenbindungssyntax können Vorlagen auch Websteuerelemente und Benutzersteuerelemente enthalten. Diese Websteuerelemente können ihre Eigenschaften über deklarative, Datenbindungssyntax zugewiesen haben oder programmgesteuert in den entsprechenden serverseitigen Ereignishandlern zugegriffen werden.

Durch das Einbetten von Steuerelementen in eine Vorlage können die Darstellung und die Benutzeroberfläche angepasst und verbessert werden. Im Tutorial Verwenden von TemplateFields im GridView-Steuerelement haben wir beispielsweise gezeigt, wie Sie die Anzeige von GridView anpassen, indem Sie ein Calendar-Steuerelement in einem TemplateField hinzufügen, um das Einstellungsdatum eines Mitarbeiters anzuzeigen. In den Tutorials Zum Hinzufügen von Validierungssteuerelementen zu den Bearbeitungs- und Einfügeschnittstellen und zum Anpassen der Datenänderungsschnittstelle haben wir erfahren, wie Sie die Bearbeitungs- und Einfügeschnittstellen anpassen, indem Sie Validierungssteuerelemente, TextBoxes, DropDownLists und andere Websteuerelemente hinzufügen.

Vorlagen können auch andere Datenwebsteuerelemente enthalten. Das heißt, wir können eine DataList haben, die eine andere DataList (oder Repeater, GridView oder DetailsView usw.) in ihren Vorlagen enthält. Die Herausforderung bei einer solchen Schnittstelle besteht darin, die entsprechenden Daten an das interne Daten-Websteuerelement zu binden. Es gibt verschiedene Ansätze, die von deklarativen Optionen mit objectDataSource bis hin zu programmgesteuerten Optionen reichen.

In diesem Tutorial erfahren Sie, wie Sie einen Repeater verwenden, der in einem anderen Repeater geschachtelt ist. Der äußere Repeater enthält ein Element für jede Kategorie in der Datenbank, das den Namen und die Beschreibung der Kategorie anzeigt. Der innere Repeater jedes Kategorieelements zeigt Informationen zu jedem Produkt, das zu dieser Kategorie gehört (siehe Abbildung 1) in einer Aufzählungsliste an. In unseren Beispielen wird veranschaulicht, wie der innere Repeater sowohl deklarativ als auch programmgesteuert aufgefüllt wird.

Jede Kategorie ist zusammen mit ihren Produkten aufgeführt.

Abbildung 1: Jede Kategorie wird zusammen mit ihren Produkten aufgelistet (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Schritt 1: Erstellen des Kategorieeintrags

Beim Erstellen einer Seite, die geschachtelte Daten-Websteuerelemente verwendet, finde ich es hilfreich, zuerst das äußerste Daten-Websteuerelement zu entwerfen, zu erstellen und zu testen, ohne sich um das innere geschachtelte Steuerelement kümmern zu müssen. Führen Sie daher zunächst die Schritte durch, die zum Hinzufügen eines Repeaters zur Seite erforderlich sind, auf der der Name und die Beschreibung für jede Kategorie aufgeführt sind.

Öffnen Sie zunächst die NestedControls.aspx Seite im DataListRepeaterBasics Ordner, fügen Sie der Seite ein Repeater-Steuerelement hinzu, und legen Sie dessen ID Eigenschaft auf fest CategoryList. Wählen Sie im Smarttag des Repeaters aus, um eine neue ObjectDataSource mit dem Namen CategoriesDataSourcezu erstellen.

Benennen Sie die neue ObjectDataSource CategoriesDataSource

Abbildung 2: Benennen Sie die neue ObjectDataSource CategoriesDataSource (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Konfigurieren Sie die ObjectDataSource so, dass sie ihre Daten aus der Methode der CategoriesBLL Klasse s GetCategories abruft.

Konfigurieren der ObjectDataSource für die Verwendung der GetCategories-Methode der CategoriesBLL-Klasse

Abbildung 3: Konfigurieren der ObjectDataSource für die Verwendung der Methode der CategoriesBLLGetCategories Klasse (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Um den Vorlageninhalt des Repeaters anzugeben, müssen Wir zur Quellansicht wechseln und die deklarative Syntax manuell eingeben. Fügen Sie ein ItemTemplate hinzu, das den Namen der Kategorie in einem <h4> Element und die Beschreibung der Kategorie in einem Absatzelement (<p>) anzeigt. Außerdem trennen wir jede Kategorie durch eine horizontale Regel (<hr>). Nachdem Sie diese Änderungen vorgenommen haben, sollte Ihre Seite eine deklarative Syntax für den Repeater und ObjectDataSource enthalten, die der folgenden ähnelt:

<asp:Repeater ID="CategoryList" DataSourceID="CategoriesDataSource"
    EnableViewState="False" runat="server">
    <ItemTemplate>
        <h4><%# Eval("CategoryName") %></h4>
        <p><%# Eval("Description") %></p>
    </ItemTemplate>
    <SeparatorTemplate>
        <hr />
    </SeparatorTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

Abbildung 4 zeigt unseren Fortschritt, wenn wir über einen Browser angezeigt werden.

Jeder Kategoriename und jede Beschreibung ist durch eine horizontale Regel getrennt aufgeführt.

Abbildung 4: Name und Beschreibung jeder Kategorie sind aufgelistet, getrennt durch eine horizontale Regel (Klicken Sie, um das bild in voller Größe anzuzeigen)

Schritt 2: Hinzufügen des geschachtelten Product Repeaters

Wenn die Kategorieliste abgeschlossen ist, besteht unsere nächste Aufgabe darin, einen Repeater zu den s ItemTemplate hinzuzufügen, der CategoryList Informationen zu den Produkten anzeigt, die zur entsprechenden Kategorie gehören. Es gibt eine Reihe von Möglichkeiten, die Daten für diesen inneren Repeater abzurufen, von denen wir in Kürze zwei untersuchen werden. Zunächst erstellen wir einfach den Produkt-Repeater innerhalb des CategoryList Repeaters ItemTemplate. Insbesondere lassen Sie den Produktwiederholungsgeber jedes Produkt in einer Aufzählungsliste mit jedem Listenelement anzeigen, das den Namen und den Preis des Produkts enthält.

Um diesen Repeater zu erstellen, müssen Sie die deklarative Syntax und die Vorlagen des inneren Repeaters manuell in die CategoryList s ItemTemplateeingeben. Fügen Sie das folgende Markup innerhalb der CategoryList Repeater-S hinzu ItemTemplate:

<asp:Repeater ID="ProductsByCategoryList" EnableViewState="False"
    runat="server">
    <HeaderTemplate>
        <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li><strong><%# Eval("ProductName") %></strong>
            (<%# Eval("UnitPrice", "{0:C}") %>)</li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>
</asp:Repeater>

Schritt 3: Binden der Category-Specific Produkte an den ProductsByCategoryList Repeater

Wenn Sie die Seite an diesem Punkt über einen Browser aufrufen, sieht Ihr Bildschirm wie in Abbildung 4 aus, da wir noch keine Daten an den Repeater binden müssen. Es gibt einige Möglichkeiten, wie wir die entsprechenden Produktdatensätze abrufen und an den Repeater binden können, einige effizienter als andere. Die Standard Herausforderung besteht hier darin, die entsprechenden Produkte für die angegebene Kategorie zurück zu erhalten.

Auf die Daten, die an das innere Repeater-Steuerelement gebunden werden sollen, kann entweder deklarativ über eine ObjectDataSource in der CategoryList Repeater-Datei ItemTemplateoder programmgesteuert über die CodeBehind-Seite der ASP.NET Seite zugegriffen werden. Auf ähnliche Weise können diese Daten entweder deklarativ an den inneren Repeater gebunden werden – über die innere Repeater-Eigenschaft oder über deklarative Datenbindungssyntax DataSourceID oder programmgesteuert durch Verweisen auf den inneren Repeater im Ereignishandler des CategoryList Repeaters ItemDataBound , programmgesteuertes Festlegen der DataSource Eigenschaft und Aufrufen der - DataBind() Methode. Lassen Sie uns jeden dieser Ansätze untersuchen.

Deklarativer Zugriff auf die Daten mit einem ObjectDataSource-Steuerelement und demItemDataBoundEreignishandler

Da wir die ObjectDataSource in dieser Tutorialreihe ausführlich verwendet haben, besteht die natürlichste Wahl für den Zugriff auf Daten für dieses Beispiel darin, bei der ObjectDataSource zu bleiben. Die ProductsBLL -Klasse verfügt über eine GetProductsByCategoryID(categoryID) -Methode, die Informationen zu den Produkten zurückgibt, die zu dem angegebenen categoryIDgehören. Aus diesem Grund können wir dem CategoryList Repeater eine ItemTemplate ObjectDataSource hinzufügen und konfigurieren, um auf die Daten dieser Klasse s-Methode zuzugreifen.

Leider lässt der Repeater das Bearbeiten seiner Vorlagen über die Entwurfsansicht nicht zu, sodass wir die deklarative Syntax für dieses ObjectDataSource-Steuerelement manuell hinzufügen müssen. Die folgende Syntax zeigt die CategoryList Repeater s ItemTemplate nach dem Hinzufügen dieses neuen ObjectDataSource (ProductsByCategoryDataSource):

<h4><%# Eval("CategoryName") %></h4>
<p><%# Eval("Description") %></p>
<asp:Repeater ID="ProductsByCategoryList" EnableViewState="False"
        DataSourceID="ProductsByCategoryDataSource" runat="server">
    <HeaderTemplate>
        <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li><strong><%# Eval("ProductName") %></strong> -
                sold as <%# Eval("QuantityPerUnit") %> at
                <%# Eval("UnitPrice", "{0:C}") %></li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="ProductsByCategoryDataSource" runat="server"
           SelectMethod="GetProductsByCategoryID" TypeName="ProductsBLL">
   <SelectParameters>
        <asp:Parameter Name="CategoryID" Type="Int32" />
   </SelectParameters>
</asp:ObjectDataSource>

Wenn Sie den ObjectDataSource-Ansatz verwenden, müssen Sie die ProductsByCategoryList Repeater-Eigenschaft DataSourceID auf die ID der ObjectDataSource (ProductsByCategoryDataSource) festlegen. Beachten Sie außerdem, dass unsere ObjectDataSource über ein <asp:Parameter> -Element verfügt, das den categoryID Wert angibt, der an die GetProductsByCategoryID(categoryID) -Methode übergeben wird. Aber wie geben wir diesen Wert an? Im Idealfall können wir einfach die DefaultValue Eigenschaft des Elements mithilfe der <asp:Parameter> Datenbindungssyntax wie folgt festlegen:

<asp:Parameter Name="CategoryID" Type="Int32"
     DefaultValue='<%# Eval("CategoryID")' />

Leider ist die Syntax der Datenbindung nur in Steuerelementen gültig, die über ein DataBinding Ereignis verfügen. Der Parameter Klasse fehlt ein solches Ereignis, weshalb die obige Syntax ungültig ist und zu einem Laufzeitfehler führt.

Um diesen Wert festzulegen, müssen wir einen Ereignishandler für das CategoryList Repeater-Ereignis ItemDataBound erstellen. Denken Sie daran, dass das ItemDataBound Ereignis einmal für jedes Element ausgelöst wird, das an den Repeater gebunden ist. Daher können wir jedes Mal, wenn dieses Ereignis für den äußeren Repeater ausgelöst wird, dem Parameter ObjectDataSource CategoryID den ProductsByCategoryDataSource aktuellen CategoryID Wert zuweisen.

Erstellen Sie mit dem folgenden Code einen Ereignishandler für das CategoryList Repeater-Ereignis ItemDataBound :

protected void CategoryList_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.AlternatingItem ||
        e.Item.ItemType == ListItemType.Item)
    {
        // Reference the CategoriesRow object being bound to this RepeaterItem
        Northwind.CategoriesRow category =
            (Northwind.CategoriesRow)((System.Data.DataRowView)e.Item.DataItem).Row;
        // Reference the ProductsByCategoryDataSource ObjectDataSource
        ObjectDataSource ProductsByCategoryDataSource =
            (ObjectDataSource)e.Item.FindControl("ProductsByCategoryDataSource");
        // Set the CategoryID Parameter value
        ProductsByCategoryDataSource.SelectParameters["CategoryID"].DefaultValue =
            category.CategoryID.ToString();
    }
}

Dieser Ereignishandler stellt zunächst sicher, dass es sich um ein Datenelement anstelle des Kopf-, Fußzeilen- oder Trennelements handelt. Als Nächstes verweisen wir auf den tatsächlichen CategoriesRow instance, der gerade an den aktuellen RepeaterItemgebunden wurde. Schließlich verweisen wir auf die ObjectDataSource im ItemTemplate und weisen ihren CategoryID Parameterwert dem CategoryID des aktuellen RepeaterItemzu.

Bei diesem Ereignishandler ist der ProductsByCategoryList Repeater in jedem RepeaterItem an diese Produkte in der RepeaterItem Kategorie s gebunden. Abbildung 5 zeigt einen Screenshot der resultierenden Ausgabe.

Der äußere Repeater Listen jede Kategorie; die innere Listen die Produkte für diese Kategorie

Abbildung 5: Der äußere Repeater Listen jede Kategorie; die innere Listen die Produkte für diese Kategorie (Klicken Sie, um das bild in voller Größe anzuzeigen)

Programmgesteuerter Zugriff auf die Produkte nach Kategoriedaten

Anstatt eine ObjectDataSource zum Abrufen der Produkte für die aktuelle Kategorie zu verwenden, könnten wir eine Methode in der CodeBehind-Klasse der ASP.NET Seite (oder im App_Code Ordner oder in einem separaten Klassenbibliotheksprojekt) erstellen, die den entsprechenden Satz von Produkten zurückgibt, wenn sie in einem CategoryIDübergeben werden. Stellen Sie sich vor, wir hätten eine solche Methode in der CodeBehind-Klasse der ASP.NET Seite und hätten den Namen GetProductsInCategory(categoryID). Mit dieser Methode könnten wir die Produkte für die aktuelle Kategorie mithilfe der folgenden deklarativen Syntax an den inneren Repeater binden:

<asp:Repeater runat="server" ID="ProductsByCategoryList" EnableViewState="False"
      DataSource='<%# GetProductsInCategory((int)(Eval("CategoryID"))) %>'>
  ...
</asp:Repeater>

Die Repeater-Eigenschaft verwendet die Datenbindungssyntax DataSource , um anzugeben, dass die Daten von der GetProductsInCategory(categoryID) -Methode stammen. Da Eval("CategoryID") ein Wert vom Typ Objectzurückgegeben wird, wird das Objekt in ein Integer umgewandelt, bevor es an die GetProductsInCategory(categoryID) -Methode übergeben wird. Beachten Sie, dass hier CategoryID über die Datenbindungssyntax der im äußeren Repeater () zugegriffen wird,CategoryList der an die Datensätze in der Categories Tabelle gebunden istCategoryID. Daher wissen wir, dass es CategoryID sich nicht um einen Datenbankwert NULL handeln kann, weshalb wir die Eval Methode blind umwandeln können, ohne zu überprüfen, ob es sich um einen DBNullhandelt.

Bei diesem Ansatz müssen wir die GetProductsInCategory(categoryID) -Methode erstellen und den entsprechenden Satz von Produkten abrufen, wenn die bereitgestellten categoryID. Dazu können Sie einfach die von der ProductsDataTableProductsBLL Klasse s-Methode GetProductsByCategoryID(categoryID) zurückgegebene zurückgeben. Erstellen Sie die GetProductsInCategory(categoryID) -Methode in der CodeBehind-Klasse für unsere NestedControls.aspx Seite. Verwenden Sie dazu den folgenden Code:

protected Northwind.ProductsDataTable GetProductsInCategory(int categoryID)
{
    // Create an instance of the ProductsBLL class
    ProductsBLL productAPI = new ProductsBLL();
    // Return the products in the category
    return productAPI.GetProductsByCategoryID(categoryID);
}

Diese Methode erstellt einfach eine instance der ProductsBLL -Methode und gibt die Ergebnisse der GetProductsByCategoryID(categoryID) Methode zurück. Beachten Sie, dass die Methode gekennzeichnet Public sein muss oder Protected; wenn die Methode markiert Privateist, ist der Zugriff über das deklarative Markup der ASP.NET Seite nicht möglich.

Nachdem Sie diese Änderungen vorgenommen haben, um diese neue Technik zu verwenden, nehmen Sie sich einen Moment Zeit, um die Seite über einen Browser anzuzeigen. Die Ausgabe sollte mit der Ausgabe bei Verwendung des ObjectDataSource- und ItemDataBound Ereignishandleransatzes identisch sein (siehe Abbildung 5, um einen Screenshot anzuzeigen).

Hinweis

Das Erstellen der Methode in der GetProductsInCategory(categoryID) CodeBehind-Klasse der ASP.NET Seite kann wie ausgelastet erscheinen. Schließlich erstellt diese Methode einfach eine instance der ProductsBLL -Klasse und gibt die Ergebnisse ihrer GetProductsByCategoryID(categoryID) Methode zurück. Warum rufen Sie diese Methode nicht einfach direkt aus der Datenbindungssyntax im inneren Repeater auf, z. B.: DataSource='<%# ProductsBLL.GetProductsByCategoryID((int)(Eval("CategoryID"))) %>'? Obwohl diese Syntax mit unserer aktuellen Implementierung der -Klasse nicht funktioniert (da es sich bei der ProductsBLLGetProductsByCategoryID(categoryID) Methode um eine instance-Methode handelt), können Sie ändernProductsBLL, um eine statische Methode einzuschließenGetProductsByCategoryID(categoryID), oder die Klasse eine statische Instance() Methode enthält, um eine neue instance der ProductsBLL -Klasse zurückzugeben.

Während solche Änderungen die Notwendigkeit der GetProductsInCategory(categoryID) Methode in der Code-Behind-Klasse der ASP.NET Seite überflüssig machen würden, bietet uns die Code-Behind-Klassenmethode mehr Flexibilität beim Arbeiten mit den abgerufenen Daten, wie wir in Kürze sehen werden.

Abrufen aller Produktinformationen auf einmal

Die beiden durchsichtigen Techniken, die wir untersucht haben, greifen diese Produkte für die aktuelle Kategorie auf, indem sie die Methode s GetProductsByCategoryID(categoryID) der ProductsBLL Klasse aufrufen (der erste Ansatz hat dies über eine ObjectDataSource, die zweite über die GetProductsInCategory(categoryID) -Methode in der CodeBehind-Klasse). Jedes Mal, wenn diese Methode aufgerufen wird, ruft die Geschäftslogikebene die Datenzugriffsebene auf, die die Datenbank mit einer SQL-Anweisung abfragt, die Zeilen aus der Products Tabelle zurückgibt, deren CategoryID Feld mit dem angegebenen Eingabeparameter übereinstimmt.

Bei N-Kategorien im System werden bei diesem Ansatz N + 1-Aufrufe an die Datenbank eine Datenbankabfrage verwendet, um alle Kategorien abzurufen, und dann N Aufrufe, um die für jede Kategorie spezifischen Produkte abzurufen. Wir können jedoch alle benötigten Daten in nur zwei Datenbankaufrufen abrufen, um alle Kategorien abzurufen, und einen anderen, um alle Produkte abzurufen. Sobald wir alle Produkte haben, können wir diese Produkte filtern, sodass nur die Produkte, die dem aktuellen CategoryID entsprechen, an den inneren Repeater dieser Kategorie gebunden sind.

Um diese Funktionalität bereitzustellen, müssen wir nur eine geringfügige Änderung an der -Methode in der GetProductsInCategory(categoryID) CodeBehind-Klasse der ASP.NET Seite vornehmen. Anstatt die Ergebnisse der Methode der ProductsBLL Klasse GetProductsByCategoryID(categoryID) blind zurückzugeben, können wir stattdessen zuerst auf alle Produkte zugreifen (sofern noch nicht darauf zugegriffen wurde) und dann nur die gefilterte Ansicht der Produkte basierend auf der übergebenen CategoryIDzurückgeben.

private Northwind.ProductsDataTable allProducts = null;
protected Northwind.ProductsDataTable GetProductsInCategory(int categoryID)
{
    // First, see if we've yet to have accessed all of the product information
    if (allProducts == null)
    {
        ProductsBLL productAPI = new ProductsBLL();
        allProducts = productAPI.GetProducts();
    }
    // Return the filtered view
    allProducts.DefaultView.RowFilter = "CategoryID = " + categoryID;
    return allProducts;
}

Beachten Sie das Hinzufügen der Variablen auf Seitenebene, allProducts. Dieser enthält Informationen zu allen Produkten und wird beim ersten Aufruf der GetProductsInCategory(categoryID) Methode aufgefüllt. Nachdem sichergestellt wurde, dass das allProducts Objekt erstellt und aufgefüllt wurde, filtert die Methode die Ergebnisse der DataTable so, dass nur auf die Zeilen zugegriffen werden kann, die CategoryID dem angegebenen CategoryID entsprechen. Dieser Ansatz reduziert die Anzahl der Zugriffe auf die Datenbank von N + 1 auf zwei.

Durch diese Erweiterung werden keine Änderungen am gerenderten Markup der Seite vorgenommen, und es werden weniger Datensätze als beim anderen Ansatz zurückgebracht. Die Anzahl der Aufrufe der Datenbank wird einfach reduziert.

Hinweis

Es könnte intuitiv sein, dass die Verringerung der Anzahl der Datenbankzugriffe die Leistung mit Sicherheit verbessern würde. Dies ist jedoch möglicherweise nicht der Fall. Wenn Sie beispielsweise über eine große Anzahl von Produkten verfügen, deren CategoryID wert ist NULL, gibt der Aufruf der GetProducts -Methode eine Anzahl von Produkten zurück, die nie angezeigt werden. Darüber hinaus kann die Rückgabe aller Produkte verschwenderisch sein, wenn Sie nur eine Teilmenge der Kategorien anzeigen, was möglicherweise der Fall ist, wenn Sie paging implementiert haben.

Wenn es wie immer um die Analyse der Leistung von zwei Techniken geht, besteht die einzige sichere Maßnahme darin, kontrollierte Tests auszuführen, die auf die gängigen Fallszenarien Ihrer Anwendung zugeschnitten sind.

Zusammenfassung

In diesem Tutorial haben wir erfahren, wie Ein Datenwebsteuerelement in einem anderen geschachtelt wird. Dabei wurde insbesondere untersucht, wie ein äußerer Repeater ein Element für jede Kategorie mit einem inneren Repeater anzeigt, der die Produkte für jede Kategorie in einer Aufzählungsliste auflistet. Die Standard Herausforderung beim Erstellen einer geschachtelten Benutzeroberfläche besteht darin, auf die richtigen Daten zuzugreifen und an das interne Datenwebsteuerelement zu binden. Es gibt eine Vielzahl von Techniken, von denen wir in diesem Tutorial zwei untersucht haben. Der erste untersuchte Ansatz verwendete eine ObjectDataSource in den äußeren Datenwebsteuerelementen, ItemTemplate die über seine DataSourceID -Eigenschaft an das interne Datenwebsteuerelement gebunden war. Die zweite Technik hat über eine Methode in der CodeBehind-Klasse der ASP.NET Seite auf die Daten zugegriffen. Diese Methode kann dann über die Datenbindungssyntax an die Eigenschaft des inneren Datenwebsteuerelements DataSource gebunden werden.

Während die in diesem Tutorial untersuchte geschachtelte Benutzeroberfläche einen in einem Repeater geschachtelten Repeater verwendet hat, können diese Techniken auf die anderen Datenwebsteuerelemente erweitert werden. Sie können einen Repeater in einer GridView oder eine GridView in einer DataList schachteln usw.

Viel Spaß beim Programmieren!

Zum Autor

Scott Mitchell, Autor von sieben ASP/ASP.NET-Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft-Webtechnologien. Scott arbeitet als unabhängiger Berater, Trainer und Autor. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Er kann unter mitchell@4GuysFromRolla.comoder über seinen Blog erreicht werden, der unter http://ScottOnWriting.NETzu finden ist.

Besonderer Dank an

Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Hauptprüfer für dieses Tutorial waren Zack Jones und Liz Shulok. Möchten Sie meine bevorstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.