Sdílet prostřednictvím


Zobrazení hlavních záznamů / podrobností v seznamu hlavních záznamů s odrážkami a podrobnostmi v prvku DataList (C#)

Scott Mitchell

Stáhnout PDF

V tomto kurzu zkomprimujeme dvoustráňovou sestavu předlohy/podrobností předchozího kurzu na jednu stránku, kde se na levé straně obrazovky zobrazí seznam názvů kategorií s odrážkami a produkty vybrané kategorie na pravé straně obrazovky.

Úvod

V předchozím kurzu jsme se podívali na to, jak oddělit sestavu předlohy a podrobností na dvou stránkách. Na stránce předlohy jsme použili ovládací prvek Repeater k vykreslení seznamu kategorií s odrážkami. Každý název kategorie byl hypertextový odkaz, který při kliknutí přešel uživatele na stránku podrobností, kde seznam DataList se dvěma sloupci ukázal tyto produkty patřící do vybrané kategorie.

V tomto kurzu zkomprimujeme dvoustráčkový kurz na jednu stránku s odrážkami se seznamem názvů kategorií na levé straně obrazovky s názvy jednotlivých kategorií vykreslenými jako LinkButton. Kliknutím na jeden z názvů kategorií LinkButtons indukuje postback a sváže vybrané produkty kategorie s dva sloupce DataList na pravé straně obrazovky. Kromě zobrazení názvu každé kategorie zobrazuje Repeater na levé straně, kolik celkového počtu produktů je pro danou kategorii (viz obrázek 1).

Na levé straně se zobrazí název kategorie a celkový počet produktů.

Obrázek 1: Na levé straně se zobrazí název kategorie a celkový počet produktů (kliknutím zobrazíte obrázek v plné velikosti).

Krok 1: Zobrazení opakovače v levé části obrazovky

Pro účely tohoto kurzu musíme, aby se nalevo od vybraných produktů kategorií zobrazoval seznam s odrážkami. Obsah webové stránky lze umístit pomocí standardních značek odstavců elementů HTML, mezer, mezer, <table> s atd. nebo prostřednictvím technik šablon stylů CSS (Cascading StyleSheet). Všechny naše kurzy zatím používaly techniky CSS pro umístění. Když jsme na stránce předlohy vytvořili uživatelské rozhraní navigace v kurzu Stránky předlohy a Navigace na webu, použili jsme absolutní umístění označující přesný posun pixelů pro navigační seznam a hlavní obsah. Šablony stylů CSS lze také použít k umístění jednoho prvku doprava nebo doleva od jiného pomocí plovoucí desetině. Seznam kategorií s odrážkami můžeme zobrazit vlevo od vybraných produktů kategorií plovoucím opakovačem nalevo od seznamu DataList.

CategoriesAndProducts.aspx Otevřete stránku ze DataListRepeaterFiltering složky a přidejte ji na stránku Repeater a DataList. Nastavte repeater s ID na Categories hodnotu DataList s na CategoryProductshodnotu . Přejděte do zobrazení Zdroj a vložte ovládací prvky Repeater a DataList do vlastních <div> prvků. To znamená, uzavřít Repeater nejprve do <div> elementu a potom DataList ve svém vlastním <div> elementu přímo za Repeater. Vaše revize by v tomto okamžiku měla vypadat nějak takto:

<div>
    <asp:Repeater ID="Categories" runat="server">
    </asp:Repeater>
</div>
<div>
    <asp:DataList ID="CategoryProducts" runat="server">
    </asp:DataList>
</div>

K plovoucímu opakovači vlevo od DataListu musíme použít float atribut stylu CSS, například takto:

<div>
    Repeater
</div>
<div>
    DataList
</div>

Plovoucí float: left; první <div> prvek vlevo od druhého prvku. padding-right Nastavení width označují první <div> s width a kolik odsazení se přidá mezi <div> obsah prvku a jeho pravý okraj. Další informace o plovoucích elementech v CSS najdete v floatutorial.

Místo určení nastavení stylu přímo prostřednictvím prvního <p> atributu elementu, style pojďme místo toho vytvořit novou třídu CSS s Styles.css názvem FloatLeft:

.FloatLeft
{
    float: left;
    width: 33%;
    padding-right: 10px;
}

Pak můžeme nahradit <div> .<div class="FloatLeft">

Po přidání třídy CSS a konfiguraci revizí na CategoriesAndProducts.aspx stránce přejděte do Návrháře. Nalevo od dataListu byste měli vidět plovoucí opakovač (i když se teď oba zobrazují jako šedá pole, protože jsme ještě nenakonfigurovali zdroje dat nebo šablony).

Repeater je plovoucí nalevo od DataList

Obrázek 2: Opakovač je plovoucí nalevo od dataListu (kliknutím zobrazíte obrázek v plné velikosti).

Krok 2: Určení počtu produktů pro každou kategorii

Po dokončení revizí Repeater a DataList s okolním kódem jsme připraveni svázat data kategorií s ovládacím prvkem Repeater. Jak ale ukazuje seznam kategorií s odrážkami na obrázku 1, kromě názvu každé kategorie musíme také zobrazit počet produktů přidružených k kategorii. Pro přístup k tomuto informacím můžeme:

  • Určete tyto informace z třídy kódu ASP.NET stránky. Vzhledem k tomu categoryID , že můžeme určit počet přidružených produktů voláním ProductsBLL metody třídy GetProductsByCategoryID(categoryID) . Tato metoda vrátí ProductsDataTable objekt, jehož Count vlastnost určuje, ProductsRow kolik s existuje, což je počet produktů pro zadané categoryID. Pro Repeater můžeme vytvořit obslužnou rutinu ItemDataBound události, která pro každou kategorii vázanou na Repeater volá metodu ProductsBLL třídy GetProductsByCategoryID(categoryID) a zahrnuje její počet ve výstupu.
  • CategoriesDataTable Aktualizujte typovou datovou sadu tak, aby zahrnovala NumberOfProducts sloupec. Pak můžeme aktualizovat metodu GetCategories() CategoriesDataTable tak, aby zahrnovala tyto informace, nebo případně ponechat GetCategories() tak, jak je, a vytvořit novou CategoriesDataTable metodu volanou GetCategoriesAndNumberOfProducts().

Pojďme prozkoumat obě tyto techniky. První přístup je jednodušší implementovat, protože nepotřebujeme aktualizovat vrstvu přístupu k datům; vyžaduje však větší komunikaci s databází. Volání ProductsBLL metody třídy GetProductsByCategoryID(categoryID) v ItemDataBound obslužné rutině události přidá dodatečné databázové volání pro každou kategorii zobrazenou v Repeateru. S touto technikou existují volání databáze N + 1, kde N je počet kategorií zobrazených v Repeateru. Při druhém přístupu se počet produktů vrátí s informacemi o jednotlivých kategoriích z CategoriesBLL metody třídy ( GetCategories() nebo GetCategoriesAndNumberOfProducts()) a výsledkem je pouze jedna cesta do databáze.

Určení počtu produktů v obslužné rutině události ItemDataBound

Určení počtu produktů pro každou kategorii v obslužné rutině události Repeater ItemDataBound s nevyžaduje žádné úpravy stávající vrstvy přístupu k datům. Všechny úpravy lze provést přímo na CategoriesAndProducts.aspx stránce. Začněte přidáním nového ObjectDataSource pojmenovaného CategoriesDataSource prostřednictvím inteligentní značky Repeater s. Dále nakonfigurujte CategoriesDataSource ObjectDataSource tak, aby načetl data z CategoriesBLL metody třídy GetCategories() .

Konfigurace ObjectDataSource pro použití CategoriesBLL třídy s GetCategories() – metoda

Obrázek 3: Konfigurace ObjectDataSource pro použití CategoriesBLL metody třídy GetCategories() (kliknutím zobrazíte obrázek plné velikosti)

Každá položka v opakovači Categories musí být kliknutá a po kliknutí může CategoryProducts seznam DataList zobrazit tyto produkty pro vybranou kategorii. Toho lze dosáhnout tak, že z každé kategorie vytvoříte hypertextový odkaz, který se vrátí na stejnou stránku (CategoriesAndProducts.aspx), ale předá CategoryID řetězec dotazu, podobně jako jsme viděli v předchozím kurzu. Výhodou tohoto přístupu je, že vyhledávací web může vytvořit záložku a indexovat stránku zobrazující konkrétní produkty kategorií.

Alternativně můžeme každou kategorii nastavit jako LinkButton, což je přístup, který použijeme pro účely tohoto kurzu. LinkButton se v prohlížeči uživatele zobrazí jako hypertextový odkaz, ale po kliknutí vyvolá postback; v postback, DataList s ObjectDataSource musí být aktualizován, aby se zobrazily tyto produkty patřící do vybrané kategorie. Pro účely tohoto kurzu dává použití hypertextového odkazu větší smysl než použití linkButtonu; mohou však existovat i jiné scénáře, kdy použití linkButton je výhodnější. I když by byl pro tento příklad ideální přístup k hypertextovým odkazům, pojďme místo toho prozkoumat použití tlačítka LinkButton. Jak uvidíme, použití linkButtonu představuje některé výzvy, které by jinak nevznikly hypertextovým odkazem. Proto použití LinkButton v tomto kurzu zvýrazní tyto výzvy a pomůže poskytnout řešení pro tyto scénáře, kdy bychom mohli chtít místo hypertextového odkazu použít linkbutton.

Poznámka:

Doporučujeme, abyste tento kurz opakovali pomocí ovládacího prvku HyperLink nebo <a> elementu místo LinkButtonu.

Následující kód ukazuje deklarativní syntaxi repeateru a ObjectDataSource. Všimněte si, že šablony Repeater s vykreslují seznam s odrážkami s každou položkou jako OdkazButton:

<asp:Repeater ID="Categories" runat="server" DataSourceID="CategoriesDataSource">
    <HeaderTemplate>
        <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li><asp:LinkButton runat="server" ID="ViewCategory" /></li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

Poznámka:

Pro účely tohoto kurzu musí mít repeater povolený stav zobrazení (všimněte si vynechání EnableViewState="False" z deklarativní syntaxe Repeater). V kroku 3 vytvoříme obslužnou rutinu události pro událost Repeater, ItemCommand ve které aktualizujeme kolekci DataList s ObjectDataSource SelectParameters . Opakovač ItemCommandse ale neaktivuje, pokud je stav zobrazení zakázaný.

LinkButton s ID hodnotou ViewCategory vlastnosti nemá jeho Text vlastnost nastavena. Pokud bychom chtěli pouze zobrazit název kategorie, nastavili bychom vlastnost Text deklarativním způsobem prostřednictvím syntaxe vazby dat, například takto:

<asp:LinkButton runat="server" ID="ViewCategory"
    Text='<%# Eval("CategoryName") %>' />

Chceme ale zobrazit název kategorie i počet produktů patřících do této kategorie. Tyto informace lze načíst z obslužné rutiny události Repeateru ItemDataBound provedením volání ProductBLL metody třídy GetCategoriesByProductID(categoryID) a určením, kolik záznamů se vrátí ve výsledku ProductsDataTable, jak ukazuje následující kód:

protected void Categories_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    // Make sure we're working with a data item...
    if (e.Item.ItemType == ListItemType.Item ||
        e.Item.ItemType == ListItemType.AlternatingItem)
    {
        // Reference the CategoriesRow instance bound to this RepeaterItem
        Northwind.CategoriesRow category =
            (Northwind.CategoriesRow) ((System.Data.DataRowView) e.Item.DataItem).Row;
        // Determine how many products are in this category
        NorthwindTableAdapters.ProductsTableAdapter productsAPI =
            new NorthwindTableAdapters.ProductsTableAdapter();
        int productCount =
            productsAPI.GetProductsByCategoryID(category.CategoryID).Count;
        // Reference the ViewCategory LinkButton and set its Text property
        LinkButton ViewCategory = (LinkButton)e.Item.FindControl("ViewCategory");
        ViewCategory.Text =
            string.Format("{0} ({1:N0})", category.CategoryName, productCount);
    }
}

Začneme tím, že zajistíme, že pracujeme s datovou položkou (je nebo ItemType Item AlternatingItem) a pak odkazujeme na CategoriesRow instanci, která byla právě svázána s aktuální .RepeaterItem Dále určíme počet produktů pro tuto kategorii vytvořením instance ProductsBLL třídy, voláním jeho GetCategoriesByProductID(categoryID) metody a určením počtu záznamů vrácených pomocí Count vlastnosti. ViewCategory Nakonec LinkButton v ItemTemplate je odkazy a jeho Text vlastnost je nastavena na CategoryName (NumberOfProductsInCategory), kde NumberOfProductsInCategory je formátován jako číslo s nulovými desetinnými místy.

Poznámka:

Alternativně jsme mohli do třídy kódu stránky ASP.NET stránky přidat funkci formátování, která přijímá kategorie s CategoryName a CategoryID hodnoty a vrací CategoryName zřetězení s počtem produktů v kategorii (jak je určeno voláním GetCategoriesByProductID(categoryID) metody). Výsledky takové funkce formátování lze deklarativním přiřazením vlastnosti Text LinkButton s nahradit potřebu obslužné rutiny ItemDataBound události. Další informace o použití funkcí formátování najdete v tématu Použití TemplateFields v ovládacím prvku GridView nebo formátování objektu DataList a Repeater na základě dat.

Po přidání této obslužné rutiny události chvíli otestujte stránku v prohlížeči. Všimněte si, že každá kategorie je uvedená v seznamu s odrážkami a zobrazuje název kategorie a počet produktů přidružených k kategorii (viz obrázek 4).

Zobrazí se název každé kategorie a počet produktů.

Obrázek 4: Zobrazí se název každé kategorie a počet produktů (kliknutím zobrazíte obrázek v plné velikosti).

CategoriesDataTableAktualizace aCategoriesTableAdapterzahrnutí počtu produktů pro každou kategorii

Místo určení počtu produktů pro každou kategorii, která je vázána na Repeater, můžeme tento proces zjednodušit úpravou CategoriesDataTable vrstvy přístupu k datům a CategoriesTableAdapter zahrnout tyto informace nativně. Abychom toho dosáhli, musíme přidat nový sloupec, který CategoriesDataTable bude obsahovat počet přidružených produktů. Pokud chcete do tabulky DataTable přidat nový sloupec, otevřete typovou datovou sadu (App_Code\DAL\Northwind.xsd), kliknutím pravým tlačítkem myši na tabulku DataTable upravte a zvolte Přidat nebo sloupec. Přidání nového sloupce do sloupce CategoriesDataTable (viz obrázek 5)

Přidání nového sloupce do KategorieDataSource

Obrázek 5: Přidání nového sloupce do obrazu CategoriesDataSource (kliknutím zobrazíte obrázek s plnou velikostí)

Tím se přidá nový sloupec s názvem Column1, který můžete změnit jednoduše zadáním jiného názvu. Přejmenujte tento nový sloupec na NumberOfProducts. Dále musíme nakonfigurovat vlastnosti tohoto sloupce. Klikněte na nový sloupec a přejděte na okno Vlastnosti. Změňte vlastnost sloupce DataType z System.String na System.Int32 a nastavte ReadOnly ji na True, jak je znázorněno na obrázku 6.

Nastavení vlastností DataType a ReadOnly nového sloupce

Obrázek 6: Nastavení DataType a ReadOnly vlastností nového sloupce

CategoriesDataTable I když teď má NumberOfProducts sloupec, jeho hodnota není nastavena žádným z odpovídajících dotazů TableAdapter. Tuto metodu můžeme aktualizovat, GetCategories() abychom tyto informace vrátili, pokud chceme tyto informace vrátit při každém načtení informací o kategoriích. Pokud ale potřebujeme získat pouze počet přidružených produktů pro kategorie ve výjimečných instancích (například jen pro účely tohoto kurzu), můžeme ponechat GetCategories() tak, jak je, a vytvořit novou metodu, která vrátí tyto informace. Pojďme použít tento druhý přístup a vytvořit novou metodu s názvem GetCategoriesAndNumberOfProducts().

Pokud chcete přidat tuto novou GetCategoriesAndNumberOfProducts() metodu CategoriesTableAdapter , klikněte pravým tlačítkem myši na příkaz Nový dotaz a zvolte Nový dotaz. Tím se zobrazí Průvodce konfigurací dotazu TableAdapter, který jsme použili mnohokrát v předchozích kurzech. Pro tuto metodu spusťte průvodce oznámením, že dotaz používá ad hoc příkaz SQL, který vrací řádky.

Vytvoření metody pomocí příkazu AD-Hoc SQL

Obrázek 7: Vytvoření metody pomocí ad hoc příkazu SQL (kliknutím zobrazíte obrázek s plnou velikostí)

Příkaz SQL vrátí řádky.

Obrázek 8: Příkaz SQL vrátí řádky (kliknutím zobrazíte obrázek s plnou velikostí)

Další obrazovka průvodce nás vyzve k zadání dotazu, který se má použít. Pokud chcete vrátit každou kategorii s CategoryID, CategoryNamea Description pole spolu s počtem produktů přidružených k dané kategorii, použijte následující SELECT příkaz:

SELECT CategoryID, CategoryName, Description,
       (SELECT COUNT(*) FROM Products p WHERE p.CategoryID = c.CategoryID)
            as NumberOfProducts
FROM Categories c

Zadání dotazu, který se má použít

Obrázek 9: Určení dotazu, který se má použít (kliknutím zobrazíte obrázek s plnou velikostí)

Všimněte si, že poddotaz, který vypočítá počet produktů přidružených k kategorii, je aliasován jako NumberOfProducts. Tato shoda pojmenování způsobí, že hodnota vrácená tímto poddotazem bude přidružena ke sloupci CategoriesDataTable s NumberOfProducts .

Po zadání tohoto dotazu je posledním krokem volba názvu nové metody. Použijte FillWithNumberOfProducts a GetCategoriesAndNumberOfProducts pro vyplnění datové tabulky a vrácení vzorů datových tabulek( v uvedeném pořadí).

Pojmenujte nové metody TableAdapter s FillWithNumberOfProducts a GetCategoriesAndNumberOfProducts

Obrázek 10: Pojmenování nových metod FillWithNumberOfProducts TableAdapter a GetCategoriesAndNumberOfProducts (kliknutím zobrazíte obrázek v plné velikosti)

V tomto okamžiku byla vrstva přístupu k datům rozšířena tak, aby zahrnovala počet produktů na kategorii. Vzhledem k tomu, že všechny naše prezentační vrstvy směrují všechna volání do DAL prostřednictvím samostatné vrstvy obchodní logiky, potřebujeme do třídy přidat odpovídající GetCategoriesAndNumberOfProducts metodu CategoriesBLL :

[System.ComponentModel.DataObjectMethodAttribute
    (System.ComponentModel.DataObjectMethodType.Select, false)]
public Northwind.CategoriesDataTable GetCategoriesAndNumberOfProducts()
{
    return Adapter.GetCategoriesAndNumberOfProducts();
}

Po dokončení DAL a BLL jsme připraveni svázat tato data s Categories Repeater v CategoriesAndProducts.aspx! Pokud jste již vytvořili ObjectDataSource pro Repeater z určení počtu produktů v ItemDataBound části Obslužná rutina událostí, odstraňte tento ObjectDataSource a odeberte nastavení vlastnosti Repeater s DataSourceID ; také odpojte událost Repeater s ItemDataBound z obslužné rutiny události odebráním Handles Categories.OnItemDataBound syntaxe v ASP.NET kód-behind třídy.

S Repeater zpět v původním stavu přidejte nový ObjectDataSource pojmenovaný CategoriesDataSource prostřednictvím inteligentní značky Repeater s. Nakonfigurujte ObjectDataSource tak, aby používal CategoriesBLL třídu, ale místo použití GetCategories() metody ji GetCategoriesAndNumberOfProducts() použijte (viz obrázek 11).

Konfigurace ObjectDataSource pro použití GetCategoriesAndNumberOfProducts – metoda

Obrázek 11: Konfigurace ObjectDataSource pro použití GetCategoriesAndNumberOfProducts metody (kliknutím zobrazíte obrázek s plnou velikostí)

Dále aktualizujte ItemTemplate vlastnost LinkButton s Text deklarativním přiřazením pomocí syntaxe vazby dat a zahrnuje jak pole, CategoryName NumberOfProducts tak i datová pole. Kompletní deklarativní kód pro Repeater a CategoriesDataSource ObjectDataSource postupujte takto:

<asp:Repeater ID="Categories" runat="server" DataSourceID="CategoriesDataSource">
    <HeaderTemplate>
        <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li><asp:LinkButton runat="server" ID="ViewCategory"
                Text='<%# String.Format("{0} ({1:N0})", _
                    Eval("CategoryName"), Eval("NumberOfProducts")) %>' />
        </li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetCategoriesAndNumberOfProducts" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

Výstup vykreslený aktualizací DAL tak, aby zahrnoval NumberOfProducts sloupec, je stejný jako použití ItemDataBound přístupu obslužné rutiny události (vraťte se na obrázek 4 a podívejte se na snímek obrazovky repeateru zobrazující názvy kategorií a počet produktů).

Krok 3: Zobrazení vybraných produktů kategorie

V tuto chvíli máme Categories Repeater zobrazující seznam kategorií spolu s počtem produktů v každé kategorii. Repeater používá linkButton pro každou kategorii, která při kliknutí způsobí postback, v jakém okamžiku potřebujeme zobrazit tyto produkty pro vybranou kategorii v seznamu CategoryProducts DataList.

Jedním z výzev, kterým čelíme, je, jak dataList zobrazit pouze ty produkty pro vybranou kategorii. V kurzu Master/Detail Pomocí vybratelné předlohy GridView s podrobnostmi DetailsView jsme viděli, jak sestavit GridView, jehož řádky lze vybrat, s vybranými podrobnostmi řádků zobrazenými v DetailsView na stejné stránce. GridView s ObjectDataSource vrátil informace o všech produktech používajících metodu ProductsBLL s GetProducts() , zatímco DetailsView s ObjectDataSource načetl informace o vybraném produktu pomocí GetProductsByProductID(productID) metody. Hodnota productID parametru byla poskytována deklarativní přidružením k hodnotě GridView s SelectedValue vlastnost. Repeater bohužel nemá SelectedValue vlastnost a nemůže sloužit jako zdroj parametrů.

Poznámka:

Jedná se o jeden z těch problémů, které se objevují při použití linkbuttonu v repeateru. Pokud jsme místo toho použili hypertextový odkaz k předání CategoryID řetězce dotazu, mohli bychom toto pole QueryString použít jako zdroj hodnoty parametru.

Než se budeme starat o nedostatek SelectedValue vlastnosti repeater, ale pojďme nejprve vytvořit vazbu DataList na ObjectDataSource a zadat jeho ItemTemplate.

Z inteligentní značky DataList se můžete rozhodnout přidat nový ObjectDataSource pojmenovaný CategoryProductsDataSource a nakonfigurovat ho tak, aby používal metodu ProductsBLL třídy.GetProductsByCategoryID(categoryID) Vzhledem k tomu, že DataList v tomto kurzu nabízí rozhraní jen pro čtení, můžete rozevírací seznamy na kartách INSERT, UPDATE a DELETE nastavit na (Žádné).

Konfigurace ObjectDataSource pro použití třídy ProductsBLL s GetProductsByCategoryID(categoryID) – metoda

Obrázek 12: Konfigurace ObjectDataSource pro použití ProductsBLL metody třídy GetProductsByCategoryID(categoryID) (kliknutím zobrazíte obrázek s plnou velikostí)

Vzhledem k tomu, že GetProductsByCategoryID(categoryID) metoda očekává vstupní parametr (categoryID), Průvodce konfigurací zdroje dat nám umožňuje určit zdroj parametrů. Pokud byly kategorie uvedeny v objektu GridView nebo DataList, nastavili jsme rozevírací seznam Zdroj parametrů na Control a ControlID na ID ovládací prvek data Webového ovládacího prvku. Vzhledem k tomu, že Repeater nemá SelectedValue vlastnost, nelze ji použít jako zdroj parametrů. Pokud zaškrtnete, zjistíte, že rozevírací seznam ControlID obsahuje pouze jeden ovládací prvek ID``CategoryProducts, dataList ID .

Prozatím nastavte rozevírací seznam Zdroj parametrů na Hodnotu Žádné. Tuto hodnotu parametru nakonec přiřadíme programově, když v repeateru klikneme na kategorii LinkButton.

Nezadávejte zdroj parametrů pro parametr categoryID.

Obrázek 13: Nezadávejte zdroj parametrů pro categoryID parametr (kliknutím zobrazíte obrázek s plnou velikostí)

Po dokončení Průvodce konfigurací zdroje dat sada Visual Studio automaticky vygeneruje DataList s ItemTemplate. Tuto výchozí hodnotu ItemTemplate nahraďte šablonou, která jsme použili v předchozím kurzu; také nastavte vlastnost DataList s RepeatColumns na hodnotu 2. Po provedení těchto změn deklarativní kód pro Váš DataList a jeho přidružený ObjectDataSource by měl vypadat takto:

<asp:DataList ID="CategoryProducts" runat="server" DataKeyField="ProductID"
    DataSourceID="CategoryProductsDataSource" RepeatColumns="2"
    EnableViewState="False">
    <ItemTemplate>
        <h5><%# Eval("ProductName") %></h5>
        <p>
            Supplied by <%# Eval("SupplierName") %><br />
            <%# Eval("UnitPrice", "{0:C}") %>
        </p>
    </ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="CategoryProductsDataSource"
    OldValuesParameterFormatString="original_{0}"  runat="server"
    SelectMethod="GetProductsByCategoryID" TypeName="ProductsBLL">
    <SelectParameters>
        <asp:Parameter Name="categoryID" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

CategoryProductsDataSource Parametr ObjectDataSource categoryID není v současné době nastaven, takže při prohlížení stránky se nezobrazují žádné produkty. Musíme udělat tuto hodnotu parametru nastavenou na CategoryID základě kategorie, na kterou jste klikli v repeateru. To představuje dvě výzvy: nejprve zjistíme, kdy bylo na tlačítko LinkButtonu v repeateru ItemTemplate kliknuto; a druhý, jak můžeme určit CategoryID odpovídající kategorii, jejíž linkButton byl kliknut?

Ovládací prvky LinkButton, jako je Button a ImageButton, mají Click událost a Command událost. Událost Click je navržená tak, aby jednoduše zaznamenala, že se kliknulo na tlačítko LinkButton. Někdy ale kromě upozornění, že LinkButton byl kliknut, musíme také předat některé další informace obslužné rutině události. Pokud se jedná o tento případ, mohou být tyto dodatečné informace přiřazeny LinkButton s CommandName a CommandArgument vlastnosti. Po kliknutí na LinkButton se událost Command aktivuje (místo události Click ) a obslužná rutina události se předá hodnotám CommandName vlastností a CommandArgument vlastnosti.

Command Když je událost vyvolána z šablony v repeateru, událost Repeater s ItemCommand se aktivuje a předá CommandName a CommandArgument hodnoty clicked LinkButton (nebo Button nebo ImageButton). Proto, abychom zjistili, kdy byla v repeateru kliknuta kategorie LinkButton, musíme udělat toto:

  1. CommandName Nastavte vlastnost LinkButton v Repeater s ItemTemplate na určitou hodnotu (používám ListProducts ). Nastavením této CommandName hodnoty se událost LinkButton s Command aktivuje při kliknutí na tlačítko LinkButton.
  2. Nastavte vlastnost LinkButton na CommandArgument hodnotu aktuální položky s CategoryID.
  3. Vytvořte obslužnou rutinu události pro událost Repeater s ItemCommand . V obslužné rutině události nastavte CategoryProductsDataSource ObjectDataSource s CategoryID parametr na hodnotu předaného CommandArgument.

Následující ItemTemplate kód pro repeater kategorie implementuje kroky 1 a 2. Všimněte si, jak CommandArgument je tato hodnota přiřazena k datové položce CategoryID pomocí syntaxe vazby dat:

<ItemTemplate>
    <li>
        <asp:LinkButton CommandName="ListProducts"  runat="server"
            CommandArgument='<%# Eval("CategoryID") %>' ID="ViewCategory"
            Text='<%# string.Format("{0} ({1:N0})", _
                Eval("CategoryName"), Eval("NumberOfProducts")) %>'>
        </asp:LinkButton>
    </li>
</ItemTemplate>

Při každém vytvoření ItemCommand obslužné rutiny události je vhodné vždy nejprve zkontrolovat příchozí CommandName hodnotu, protože jakákoli Command událost vyvolaná tlačítkem , LinkButton nebo ImageButton v repeateru způsobí ItemCommand , že událost se aktivuje. V současné době máme pouze jeden takový LinkButton, v budoucnu můžeme (nebo jiný vývojář v našem týmu) přidat další webové ovládací prvky tlačítka repeater, které po kliknutí vyvolá stejnou obslužnou ItemCommand rutinu události. Proto je nejlepší vždy zkontrolovat CommandName vlastnost a pokračovat pouze s programovou logikou, pokud odpovídá očekávané hodnotě.

Po zajištění, že předaná CommandName hodnota se rovná ListProducts, obslužná rutina události pak přiřadí CategoryProductsDataSource ObjectDataSource CategoryID s parametr k hodnotě předaného CommandArgument. Tato úprava ObjectDataSource automaticky SelectParameters způsobí, že DataList se znovu propojí se zdrojem dat a zobrazí produkty pro nově vybranou kategorii.

protected void Categories_ItemCommand(object source, RepeaterCommandEventArgs e)
{
    // If it's the "ListProducts" command that has been issued...
    if (string.Compare(e.CommandName, "ListProducts", true) == 0)
    {
        // Set the CategoryProductsDataSource ObjectDataSource's CategoryID parameter
        // to the CategoryID of the category that was just clicked (e.CommandArgument)...
        CategoryProductsDataSource.SelectParameters["CategoryID"].DefaultValue =
            e.CommandArgument.ToString();
    }
}

S těmito doplňky je náš kurz dokončen! Chvíli to otestujte v prohlížeči. Obrázek 14 znázorňuje obrazovku při první návštěvě stránky. Vzhledem k tomu, že kategorie ještě není vybraná, nezobrazují se žádné produkty. Kliknutím na kategorii, například Produkt, zobrazíte tyto produkty v kategorii Produkt v zobrazení se dvěma sloupci (viz obrázek 15).

Při první návštěvě stránky se nezobrazují žádné produkty.

Obrázek 14: Při první návštěvě stránky se nezobrazují žádné produkty (kliknutím zobrazíte obrázek v plné velikosti).

Kliknutím na položku Vytvořit kategorii zobrazíte odpovídající produkty napravo.

Obrázek 15: Kliknutím na položku Vytvořit kategorii zobrazíte odpovídající produkty vpravo (kliknutím zobrazíte obrázek s plnou velikostí).

Shrnutí

Jak jsme viděli v tomto kurzu a v předchozím kurzu, hlavní/podrobné sestavy se dají rozprostřet na dvě stránky nebo je sloučit na jednu. Zobrazení sestavy předlohy/podrobností na jedné stránce ale představuje několik problémů s tím, jak nejlépe rozložení záznamů předlohy a podrobností na stránce. V kurzu Master/Detail Using a Selectable Master GridView s podrobnostmi DetailsView jsme měli záznamy podrobností zobrazené nad hlavními záznamy. V tomto kurzu jsme použili techniky CSS k tomu, aby hlavní záznamy byly plovoucí nalevo od podrobností.

Spolu se zobrazením sestav hlavních/podrobností jsme také měli příležitost prozkoumat, jak načíst počet produktů přidružených k jednotlivým kategoriím a jak provádět logiku na straně serveru při kliknutí na tlačítko LinkButton (nebo Button nebo ImageButton) z repeateru.

Tento kurz dokončí naši zkoušku hlavních a podrobných sestav pomocí DataListu a Repeateru. Naše další sada kurzů vám ukáže, jak do ovládacího prvku DataList přidat možnosti úprav a odstraňování.

Šťastné programování!

Další čtení

Další informace o tématech probíraných v tomto kurzu najdete v následujících zdrojích informací:

O autorovi

Scott Mitchell, autor sedmi knih ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, trenér a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 za 24 hodin. Je dostupný na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím svého blogu, který lze najít na http://ScottOnWriting.NET.

Zvláštní díky

Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Hlavním recenzentem tohoto kurzu byl Zack Jones. Chcete si projít nadcházející články MSDN? Pokud ano, zahoďte mi řádek na mitchell@4GuysFromRolla.com.