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ánkovou sestavu předlohy a podrobností z předchozího kurzu na jednu stránku a zobrazíme seznam názvů kategorií s odrážkami na levé straně obrazovky a produkty vybrané kategorie na pravé straně obrazovky.

Úvod

V předchozím kurzu jsme se podívali na to, jak oddělit hlavní a podrobnou sestavu na dvě stránky. Na stránce předlohy jsme použili ovládací prvek Repeater k vykreslení seznamu kategorií s odrážkami. Název každé kategorie byl hypertextový odkaz, který uživatele po kliknutí přemístit na stránku podrobností, kde dvousloupce DataList zobrazil produkty, které patří do vybrané kategorie.

V tomto kurzu zkomprimujeme dvoustránkové kurzy do jedné stránky a zobrazíme seznam názvů kategorií s odrážkami na levé straně obrazovky, přičemž každý název kategorie se zobrazí jako OdkazButton. Kliknutím na jednu z kategorií s názvem LinkButtons vyvoláte postback a svážete vybrané produkty kategorií s dvousloupcovým seznamem DataList na pravé straně obrazovky. Kromě zobrazení názvu jednotlivých kategorií zobrazuje Repeater na levé straně celkový počet produktů pro danou kategorii (viz obrázek 1).

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

Obrázek 1: Vlevo 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 potřebujeme, aby se nalevo od vybraných produktů kategorií zobrazil seznam kategorií s odrážkami. Obsah v rámci webové stránky lze umístit pomocí standardních značek odstavců elementů HTML, mezer, mezer, <table> s atd. nebo prostřednictvím technik css (CSS). Všechny naše kurzy dosud používaly techniky CSS pro umístění. Při sestavování uživatelského rozhraní navigace na stránce předlohy v kurzu Stránky předlohy a Navigace na webu jsme použili absolutní umístění, které označuje 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 nalevo od druhého prostřednictvím plovoucí. Seznam kategorií s odrážkami můžeme zobrazit nalevo od vybraných produktů kategorií tak, že opakovač se zobrazí nalevo od datalistu.

CategoriesAndProducts.aspx Otevřete stránku ze DataListRepeaterFiltering složky a přidejte na stránku Repeater a DataList. Nastavte Repeater s ID na Categories a DataList s na CategoryProducts. Přejděte do zobrazení Zdroj a vložte ovládací prvky Repeater a DataList do jejich vlastních <div> prvků. To znamená, že nejprve uzavřete Repeater do elementu <div> a pak DataList do vlastního <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>

Pokud chceme opakovač uvolnit nalevo od DataListu, musíme použít float atribut stylu CSS, například takto:

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

První float: left; prvek je plovoucí <div> nalevo od druhého prvku. Nastavení width a padding-right označují první <div> s width a kolik odsazení je přidáno mezi obsah elementu <div> s a jeho pravý okraj. Další informace o plovoucích elementech v css najdete v článku Floatutorial.

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

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

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

Po přidání třídy CSS a konfiguraci značek na CategoriesAndProducts.aspx stránce přejděte na Designer. Měl by se zobrazit opakovač plovoucí nalevo od seznamu DataList (i když se teď obě zobrazují jenom jako šedá pole, protože jsme ještě nenakonfigurovali jejich zdroje dat nebo šablony).

Opakovač je plovoucí nalevo od seznamu 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í značek Repeater a DataList s kolem jsme připraveni vytvořit vazbu dat kategorií s ovládacím prvkem Repeater. Jak ale ukazuje seznam kategorií s odrážkami na obrázku 1, musíme kromě názvu každé kategorie zobrazit také počet produktů přidružených k dané kategorii. Pro přístup k tomuto údaji můžeme:

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

Pojďme se podívat na obě tyto techniky. První přístup je jednodušší implementovat, protože nemusíme aktualizovat vrstvu přístupu k datům. vyžaduje však větší komunikaci s databází. Volání ProductsBLL metody třídy s GetProductsByCategoryID(categoryID) v obslužné rutině ItemDataBound události přidá další volání databáze 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 vrátí počet produktů s informacemi o jednotlivých kategoriích z CategoriesBLL metody třídy GetCategories() s (nebo GetCategoriesAndNumberOfProducts()), což vede k jedinému výletu 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 s ItemDataBound nevyžaduje žádné úpravy naší stávající vrstvy přístupu k datům. Všechny změny lze provést přímo na CategoriesAndProducts.aspx stránce. Začněte přidáním nového objektu ObjectDataSource s pomocí CategoriesDataSource inteligentní značky Repeater s. Dále nakonfigurujte CategoriesDataSource ObjectDataSource tak, aby načetl data z CategoriesBLL metody třídy s GetCategories() .

Nakonfigurujte ObjectDataSource tak, aby používal třídu CategoriesBLL s metodou GetCategories()

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

Na každou položku v Categories opakovacím nástroji musí být možné kliknout a po kliknutí způsobit, že CategoryProducts dataList zobrazí tyto produkty pro vybranou kategorii. Toho lze dosáhnout tak, že se z každé kategorie vytvoří hypertextový odkaz, který propojí zpět na stejnou stránku (CategoriesAndProducts.aspx), ale projde CategoryID řetězcem dotazů, podobně jako jsme to viděli v předchozím kurzu. Výhodou tohoto přístupu je, že stránku zobrazující konkrétní produkty kategorie s může být záložkou a indexována vyhledávacím webem.

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

Poznámka

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

Následující kód ukazuje deklarativní syntaxi pro Repeater 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 opakovač povolený stav zobrazení (všimněte si vynechání EnableViewState="False" deklarativní syntaxe repeateru). V kroku 3 vytvoříme obslužnou rutinu události pro událost Repeater, ItemCommand ve které aktualizujeme kolekci DataList s ObjectDataSource SelectParameters . Opakovač se ItemCommandale neaktivuje, pokud je stav zobrazení zakázaný.

LinkButton s ID hodnotou ViewCategory vlastnosti nemá nastavenou vlastnost Text . Kdybychom chtěli jenom zobrazit název kategorie, nastavili bychom vlastnost Text deklarativně 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ů, které do této kategorie patří. Tyto informace lze načíst z obslužné rutiny události Repeater s ItemDataBound provedením volání ProductBLL metody třídy s GetCategoriesByProductID(categoryID) a určením, kolik záznamů se vrátí ve výsledném ProductsDataTableobjektu , 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 (ta, jejíž ItemType je Item nebo AlternatingItem) a potom odkazujeme na CategoriesRow instanci, která byla právě svázaná s aktuální RepeaterItempoložkou . Dále určíme počet produktů pro tuto kategorii vytvořením instance ProductsBLL třídy, voláním její 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áno jako číslo s nulovými desetinnými místy.

Poznámka

Případně bychom mohli do třídy kódu na pozadí stránky ASP.NET přidat funkci formátování , která přijímá hodnoty kategorie s CategoryName a CategoryID a vrací CategoryName zřetězené hodnoty s počtem produktů v kategorii (jak je určeno voláním GetCategoriesByProductID(categoryID) metody). Výsledky takové funkce formátování by mohly být deklarativně přiřazeny vlastnosti LinkButton s Text nahrazující potřebu obslužné rutiny ItemDataBound události. Další informace o použití funkcí formátování najdete v kurzech Použití polí šablon v ovládacím prvku GridViewnebo Formátování seznamu dat a opakovače založeného na datech .

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 dané 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 aCategoriesTableAdapterna zahrnutí 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 a CategoriesTableAdapter ve vrstvě přístupu k datům tak, aby tyto informace zahrnovaly nativně. Abychom toho dosáhli, musíme do ní přidat nový sloupec CategoriesDataTable , který bude obsahovat počet přidružených produktů. Pokud chcete do tabulky DataTable přidat nový sloupec, otevřete sadu Typed DataSet (App_Code\DAL\Northwind.xsd), klikněte pravým tlačítkem myši na tabulku Dat, která chcete upravit, a zvolte Přidat / Sloupec. Přidejte do CategoriesDataTable pole nový sloupec (viz Obrázek 5).

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

Obrázek 5: Přidání nového sloupce do CategoriesDataSource (kliknutím zobrazíte obrázek v plné velikosti)

Tím přidáte 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 vlastnost ReadOnly na True, jak je znázorněno na obrázku 6.

Nastavení vlastností DataType a ReadOnly nového sloupce

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

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

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

Vytvoření metody pomocí ad hoc příkazu SQL

Obrázek 7: Vytvoření metody pomocí ad hoc příkazu SQL (kliknutím zobrazíte obrázek v plné velikosti)

Příkaz SQL vrací řádky.

Obrázek 8: Příkaz SQL vrací řádky (kliknutím zobrazíte obrázek v plné velikosti)

Na další obrazovce průvodce se zobrazí výzva k použití dotazu. Pokud chcete vrátit všechna pole kategorií CategoryID, CategoryNamea Description společně 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

Určení dotazu, který se má použít

Obrázek 9: Určení dotazu, který se má použít (kliknutím zobrazíte obrázek v plné velikosti)

Všimněte si, že poddotaz, který vypočítá počet produktů přidružených ke kategorii, má alias NumberOfProducts. Tato shoda názvů 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. Pro vzory Fill a DataTable a Return a DataTable použijte FillWithNumberOfProducts a GetCategoriesAndNumberOfProducts .

Pojmenujte metody New TableAdapter FillWithNumberOfProducts a GetCategoriesAndNumberOfProducts.

Obrázek 10: Pojmenujte nové metody 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šechna naše prezentační vrstva směruje všechna volání dal prostřednictvím samostatné vrstvy obchodní logiky, musíme 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 repeaterem Categories v CategoriesAndProducts.aspx! Pokud jste již vytvořili ObjectDataSource pro repeater z určení počtu produktů v ItemDataBound části Obslužná rutina události, odstraňte tento ObjectDataSource a odeberte nastavení vlastnosti Repeater s DataSourceID . Také odpojte událost Repeater s ItemDataBound z obslužné rutiny události tím, že odeberete Handles Categories.OnItemDataBound syntaxi ve třídě kódu ASP.NET na pozadí.

Vraťte repeater do původního stavu a přidejte nový ObjectDataSource s názvem CategoriesDataSource prostřednictvím inteligentní značky Repeater. Nakonfigurujte ObjectDataSource tak, aby používal CategoriesBLL třídu , ale místo toho ji nechte použít GetCategoriesAndNumberOfProducts() metodu GetCategories() (viz obrázek 11).

Nakonfigurujte ObjectDataSource tak, aby používal metodu GetCategoriesAndNumberOfProducts.

Obrázek 11: Konfigurace objektu ObjectDataSource pro použití GetCategoriesAndNumberOfProducts metody (kliknutím zobrazíte obrázek v plné velikosti)

Dále aktualizujte ItemTemplate tak, aby vlastnost LinkButton s Text byla deklarativně přiřazena pomocí syntaxe vazby dat a zahrnovala CategoryName datová pole a NumberOfProducts . Úplný deklarativní kód pro Repeater a CategoriesDataSource ObjectDataSource následuje:

<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 při použití ItemDataBound přístupu obslužné rutiny události (podívejte se zpět na Obrázek 4 a podívejte se na snímek obrazovky repeateru s názvy kategorií a počtem produktů).

Krok 3: Zobrazení vybrané kategorie produktů

V tomto okamžiku se v opakovači Categories zobrazuje 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í zpětné odeslání. V tomto okamžiku musíme zobrazit tyto produkty pro vybranou kategorii v CategoryProducts Seznamu dat.

Jednou z výzev, kterým čelíme, je, jak nechat dataList zobrazit jenom produkty pro vybranou kategorii. V kurzu Master/Detail Pomocí vybratelného hlavního objektu GridView s podrobnostmi DetailsView jsme viděli, jak vytvořit Objekt GridView, jehož řádky lze vybrat, přičemž podrobnosti vybraného řádku se zobrazí v zobrazení DetailsView na stejné stránce. GridView s ObjectDataSource vrátil informace o všech produktech pomocí ProductsBLL metody s GetProducts() , zatímco DetailsView s ObjectDataSource načetl informace o vybraném produktu pomocí GetProductsByProductID(productID) metody . Hodnota productID parametru byla poskytnuta 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

Toto je jeden z problémů, které se objevují při použití LinkButton v repeateru. Kdybychom místo toho pomocí řetězce dotazu předali CategoryID hypertextový odkaz, mohli bychom jako zdroj pro hodnotu parametru s použít toto pole QueryString.

Než se však začneme starat o chybějící SelectedValue vlastnost pro Repeater, pojďme nejprve vytvořit vazbu DataList na ObjectDataSource a zadat jeho ItemTemplate.

Z inteligentní značky DataList zvolte přidání nového objektu ObjectDataSource s názvem CategoryProductsDataSource a nakonfigurujte ho tak, aby používal metodu ProductsBLL třídy s 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 objektu ObjectDataSource pro použití třídy ProductsBLL s metodou GetProductsByCategoryID(categoryID)

Obrázek 12: Konfigurace objektu ObjectDataSource pro použití ProductsBLL metody třídy GetProductsByCategoryID(categoryID) (kliknutím zobrazíte obrázek v plné velikosti)

Vzhledem k tomu, že GetProductsByCategoryID(categoryID) metoda očekává vstupní parametr (categoryID), průvodce Konfigurovat zdroj dat nám umožňuje zadat zdroj parametru s. Pokud by kategorie byly uvedeny v objektu GridView nebo DataList, nastavili jsme rozevírací seznam Zdroj parametrů na Control a ControlID na ID datový webový ovládací prvek. Vzhledem k tomu, že repeater nemá SelectedValue vlastnost, nelze jej použít jako zdroj parametrů. Pokud to zaškrtnete, zjistíte, že rozevírací seznam ControlID obsahuje jenom jeden ovládací prvek ID``CategoryProducts, ID ze seznamu Dat.

Prozatím nastavte rozevírací seznam Zdroj parametrů na Žádný. Nakonec tuto hodnotu parametru přiřadíme programově, když se v repeateru klikne na kategorii LinkButton.

Nezadávejte zdroj parametrů pro parametr categoryID

Obrázek 13: Nezadávejte zdroj parametru categoryID pro parametr (kliknutím zobrazíte obrázek v plné velikosti)

Po dokončení průvodce Konfigurací zdroje dat sada Visual Studio automaticky vygeneruje dataList s ItemTemplate. Nahraďte toto výchozí nastavení ItemTemplate šablonou, která byla použita v předchozím kurzu. Nastavte také vlastnost DataList s RepeatColumns na hodnotu 2. Po provedení těchto změn by deklarativní kód pro dataList a jeho přidružený ObjectDataSource 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 V současné době není parametr ObjectDataSource s categoryID nikdy nastaven, takže se při prohlížení stránky nezobrazí žádné produkty. Co musíme udělat, je mít tuto hodnotu parametru nastavenou CategoryID na základě kategorie, na kterou jste klikli v repeateru. To přináší dvě výzvy: za prvé, jak určíme, kdy bylo kliknutí na Tlačítko LinkButton v repeateru ItemTemplate , a za druhé, jak můžeme určit CategoryID odpovídající kategorii, jejíž tlačítko LinkButton bylo kliklo?

Ovládací prvky LinkButton, jako je Button a ImageButton, Click mají událost a Command událost. Událost je navržená Click tak, aby jednoduše zaznamenala, že se kliklo na tlačítko LinkButton. Občas ale kromě toho, že jsme klikli na tlačítko LinkButton, musíme obslužné rutině události předat i další informace. V takovém případě je možné tyto dodatečné informace přiřadit vlastnostem LinkButton s CommandName a CommandArgument . Po kliknutí na LinkButton se jeho Command událost aktivuje (místo události Click ) a obslužné rutině události se předají hodnoty CommandName vlastností a CommandArgument .

Command Když je událost vyvolána z šablony v repeateru, aktivuje se událost Repeater s ItemCommand a předá CommandName se hodnoty a CommandArgument klepnutého tlačítka LinkButton (nebo Button nebo ImageButton). Proto k určení, kdy bylo kliknutí na kategorii LinkButton v repeateru, musíme provést následující kroky:

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

Následující ItemTemplate kód pro repeater kategorií implementuje kroky 1 a 2. Všimněte si, jak je CommandArgument hodnota přiřazena datové položce s 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 vytváření obslužné ItemCommand rutiny události je vhodné vždy nejprve zkontrolovat příchozí CommandName hodnotu, protože jakákoliCommand událost vyvolaná libovolným Button, LinkButton nebo ImageButton v repeateru způsobí ItemCommand , že událost se aktivuje. I když v současné době máme nyní pouze jeden takový LinkButton, v budoucnu můžeme (nebo jiný vývojář v našem týmu) přidat další tlačítko Webové ovládací prvky repeater, které po kliknutí vyvolá stejnou obslužnou ItemCommand rutinu události. Proto je nejlepší vždy zkontrolovat CommandName vlastnost a pokračovat v programové logice pouze v případě, že odpovídá očekávané hodnotě.

Po ověření, že se předaná CommandName hodnota rovná ListProducts, obslužná rutina události pak přiřadí CategoryProductsDataSource parametr ObjectDataSource s CategoryID k hodnotě předané CommandArgument. Tato úprava objektu ObjectDataSource SelectParameters automaticky způsobí, že dataList se znovu připojí ke zdroji 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 si to vyzkoušejte v prohlížeči. Obrázek 14 ukazuje obrazovku při první návštěvě stránky. Vzhledem k tomu, že kategorie ještě nebyla vybrána, nezobrazí se žádné produkty. Kliknutím na kategorii, například Plodiny, se tyto produkty zobrazí v kategorii Produkt ve dvou sloupcích (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 Kategorii plodin Seznamy odpovídající produkty vpravo

Obrázek 15: Kliknutím na kategorii Plodin Seznamy odpovídající produkty napravo (kliknutím zobrazíte obrázek v plné velikosti)

Souhrn

Jak jsme viděli v tomto a předchozím kurzu, hlavní a podrobné sestavy je možné rozprostřít na dvě stránky nebo konsolidovat na jedné. Zobrazení sestavy předlohy nebo podrobností na jedné stránce však přináší určité problémy, pokud jde o nejlepší rozložení předlohy a podrobných záznamů na stránce. V kurzu Master/ Detail Using a Selectable Master GridView with a Details DetailsView jsme měli podrobnosti záznamy se zobrazovat 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 hlavních sestav a sestav podrobností jsme měli také možnost 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 zakončuje naši zkoušku řídicích/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í.

Všechno nejlepší na 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 o ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, školitel a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Můžete ho zastihnout na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na adrese http://ScottOnWriting.NET.

Zvláštní poděkování

Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Hlavním recenzentem pro tento kurz byl Zack Jones. Chtěli byste si projít své nadcházející články na webu MSDN? Pokud ano, dejte mi řádek na mitchell@4GuysFromRolla.com.