Filtrování předlohy a podrobností na dvou stránkách pomocí ovládacího prvku Repeater a DataList (C#)
V tomto kurzu se podíváme na to, jak rozdělit hlavní a podrobnou sestavu na dvě stránky. Na stránce předlohy použijeme ovládací prvek Repeater k vykreslení seznamu kategorií, které po kliknutí uživatele převedou na stránku "podrobností", kde seznam DataList se dvěma sloupci zobrazuje produkty patřící do vybrané kategorie.
Úvod
V předchozím kurzu jsme viděli, jak zobrazit hlavní a podrobné sestavy na jedné webové stránce pomocí DropDownLists k zobrazení "hlavních" záznamů a DataList pro zobrazení "podrobností". Dalším běžným vzorem, který se používá pro hlavní nebo podrobné sestavy, je mít hlavní záznamy na jedné webové stránce a podrobnosti na druhé. V předchozím kurzu Filtrování předlohy a podrobností na dvou stránkách jsme tento vzor prozkoumali pomocí zobrazení GridView k zobrazení všech dodavatelů v systému. Toto zobrazení GridView obsahovalo pole HyperLinkField, které se vykreslilo jako odkaz na druhou stránku a předávalo ho SupplierID
v řetězci dotazu. Druhá stránka použila GridView k výpisu produktů poskytovaných vybraným dodavatelem.
Tyto dvoustránkové sestavy předlohy a podrobností lze také provádět pomocí ovládacích prvků DataList a Repeater. Jediným rozdílem je, že dataList ani repeater poskytují podporu pro ovládací prvek HyperLinkField. Místo toho musíme přidat webový ovládací prvek HyperLink nebo element HTML ukotvení (<a>
) v rámci ovládacího prvku ItemTemplate
. Vlastnost HyperLink NavigateUrl
nebo atribut ukotvení href
je pak možné přizpůsobit pomocí deklarativních nebo programových přístupů.
V tomto kurzu prozkoumáme příklad, který uvádí kategorie v seznamu s odrážkami na jedné stránce pomocí ovládacího prvku Repeater. Každá položka seznamu bude obsahovat název a popis kategorie, přičemž název kategorie se zobrazí jako odkaz na druhou stránku. Kliknutím na tento odkaz přejdete uživatele na druhou stránku, kde se v seznamu DataList zobrazí produkty, které patří do vybrané kategorie.
Krok 1: Zobrazení kategorií v seznamu s odrážkami
Prvním krokem při vytváření jakékoli hlavní/podrobné sestavy je začít zobrazením "hlavních" záznamů. Proto je naším prvním úkolem zobrazit kategorie na stránce předlohy. CategoryListMaster.aspx
Otevřete stránku ve DataListRepeaterFiltering
složce, přidejte ovládací prvek Repeater a z inteligentní značky zvolte přidání nového ObjectDataSource. Nakonfigurujte nový ObjectDataSource tak, aby přistupoval k datům z CategoriesBLL
metody třídy GetCategories
(viz Obrázek 1).
Obrázek 1: Konfigurace objektu ObjectDataSource pro použití CategoriesBLL
metody třídy GetCategories
(kliknutím zobrazíte obrázek v plné velikosti)
Dále definujte šablony repeateru tak, aby zobrazovaly název a popis každé kategorie jako položku v seznamu s odrážkami. Zatím si nedělejme starosti s odkazem na každou kategorii na stránku podrobností. Následující příklad ukazuje deklarativní značky pro Repeater a ObjectDataSource:
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="ObjectDataSource1"
EnableViewState="False">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li><%# Eval("CategoryName") %> - <%# Eval("Description") %></li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
Po dokončení této značky si chvíli prohlédněte průběh v prohlížeči. Jak ukazuje obrázek 2, Opakovač se vykresluje jako seznam s odrážkami, který zobrazuje název a popis jednotlivých kategorií.
Obrázek 2: Každá kategorie se zobrazí jako položka seznamu s odrážkami (kliknutím zobrazíte obrázek v plné velikosti)
Krok 2: Přeměna názvu kategorie na odkaz na stránku podrobností
Pokud chcete uživateli povolit zobrazení "podrobností" pro danou kategorii, musíme přidat odkaz na každou položku seznamu s odrážkami, který po kliknutí uživatele přemístit na druhou stránku (ProductsForCategoryDetails.aspx
). Na této druhé stránce se pak zobrazí produkty pro vybranou kategorii pomocí seznamu DataList. Abychom mohli určit kategorii, na jejíž odkaz se kliknulo, musíme pomocí nějakého mechanismu předat klikané kategorie CategoryID
na druhou stránku. Nejjednodušším a nejjednodušším způsobem přenosu skalárních dat z jedné stránky na jinou je použití řetězce dotazů, což je možnost, kterou použijeme v tomto kurzu. Stránka bude zejména očekávat předání ProductsForCategoryDetails.aspx
vybrané categoryID
hodnoty přes pole řetězce dotazu s názvem CategoryID
. Pokud například chcete zobrazit produkty pro kategorii Nápoje, která má CategoryID
1, uživatel navštíví ProductsForCategoryDetails.aspx?CategoryID=1
.
Pokud chcete vytvořit hypertextový odkaz pro každou položku seznamu s odrážkami v repeateru, musíme buď přidat ovládací prvek HyperLink Web, nebo element ukotvení HTML (<a>
) do ItemTemplate
. Ve scénářích, kdy se hypertextový odkaz zobrazuje stejně pro každý řádek, bude stačit každý přístup. U repeaterů dávám přednost použití elementu ukotvení. Pokud chcete použít element anchor, aktualizujte ItemTemplate repeateru na:
<li>
<a href='ProductsForCategoryDetails.aspx?CategoryID=<%# Eval("CategoryID") %>'>
<%# Eval("CategoryName") %>
</a> - <%# Eval("Description") %>
</li>
Všimněte si, že CategoryID
objekt může být vložen přímo do atributu elementu href
ukotvení, ale abyste to udělali, nezapomeňte oddělovat href
hodnotu atributu apostrofy (a všimněte si uvozovek), protože Eval
metoda v atributu href
odděluje řetězec ("CategoryID"
) uvozovkami. Případně můžete místo toho použít webový ovládací prvek HyperLink:
<li>
<asp:HyperLink runat="server" Text='<%# Eval("CategoryName") %>'
NavigateUrl='<%# "ProductsForCategoryDetails.aspx?CategoryID=" &
Eval("CategoryID") %>'>
</asp:HyperLink>
- <%# Eval("Description") %>
</li>
Všimněte si, že statická část adresy URL je ProductsForCategoryDetails.aspx?CategoryID
připojena k výsledku Eval("CategoryID")
přímo v rámci syntaxe vazby dat pomocí zřetězení řetězců.
Jednou z výhod použití ovládacího prvku HyperLink je, že k němu lze v případě potřeby přistupovat programově z obslužné rutiny události Repeateru ItemDataBound
. Můžete například chtít zobrazit název kategorie jako text, nikoli jako odkaz na kategorie bez přidružených produktů. Takovou kontrolu lze provést programově v ItemDataBound
obslužné rutině události. U kategorií bez přidružených produktů může být vlastnost HyperLink NavigateUrl
nastavena na prázdný řetězec, což vede k tomu, že se název konkrétní kategorie vykresluje jako prostý text (nikoli jako odkaz). Další informace o formátování obsahu datalistu a opakovače založeného na datech najdete v kurzu Formátování seznamu dat a opakovače na základě programové logiky prostřednictvím ItemDataBound
obslužné rutiny události.
Pokud postupujete podle pokynů, můžete na stránce použít buď element ukotvení, nebo přístup k ovládacímu prvku HyperLink. Bez ohledu na přístup by se při prohlížení stránky v prohlížeči měl každý název kategorie vykreslit jako odkaz na ProductsForCategoryDetails.aspx
a předat příslušnou CategoryID
hodnotu (viz obrázek 3).
Obrázek 3: Odkaz na názvy ProductsForCategoryDetails.aspx
kategorií (kliknutím zobrazíte obrázek v plné velikosti)
Krok 3: Výpis produktů, které patří do vybrané kategorie
CategoryListMaster.aspx
Po dokončení stránky jsme připraveni obrátit pozornost na implementaci stránky ProductsForCategoryDetails.aspx
"podrobnosti" . Otevřete tuto stránku, přetáhněte DataList ze sady nástrojů do Designer a nastavte jeho ID
vlastnost na ProductsInCategory
. Dále z inteligentní značky DataList zvolte přidat na stránku nový ObjectDataSource a pojmovte ji ProductsInCategoryDataSource
. Nakonfigurujte ji tak, aby volal metodu ProductsBLL
třídy GetProductsByCategoryID(categoryID)
; nastavte rozevírací seznamy na kartách INSERT, UPDATE a DELETE na (None).
Obrázek 4: 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 přijímá vstupní parametr (categoryID
), nabízí průvodce Zvolit zdroj dat možnost určit zdroj parametru. Nastavte zdroj parametru na QueryString pomocí QueryStringField CategoryID
.
Obrázek 5: Použití pole CategoryID
řetězce dotazu jako zdroje parametru (kliknutím zobrazíte obrázek v plné velikosti)
Jak jsme viděli v předchozích kurzech, visual Studio po dokončení průvodce Zvolit zdroj dat automaticky vytvoří pro Seznam dat seznam ItemTemplate
, který obsahuje seznam názvů a hodnot jednotlivých datových polí. Tuto šablonu nahraďte šablonou, která obsahuje pouze název, dodavatele a cenu produktu. Nastavte také vlastnost DataList RepeatColumns
na hodnotu 2. Po těchto změnách by deklarativní značky DataList a ObjectDataSource měly vypadat podobně jako následující:
<asp:DataList ID="ProductsInCategory" runat="server" DataKeyField="ProductID"
RepeatColumns="2" DataSourceID="ProductsInCategoryDataSource"
EnableViewState="False">
<ItemTemplate>
<h5><%# Eval("ProductName") %></h5>
<p>
Supplied by <%# Eval("SupplierName") %><br />
<%# Eval("UnitPrice", "{0:C}") %>
</p>
</ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="ProductsInCategoryDataSource"
OldValuesParameterFormatString="original_{0}" runat="server"
SelectMethod="GetProductsByCategoryID" TypeName="ProductsBLL">
<SelectParameters>
<asp:QueryStringParameter Name="categoryID" QueryStringField="CategoryID"
Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
Pokud chcete zobrazit tuto stránku v akci, začněte od CategoryListMaster.aspx
stránky. Potom klikněte na odkaz v seznamu kategorií s odrážkami. Tímto způsobem přejdete na ProductsForCategoryDetails.aspx
adresu a projdete CategoryID
řetězcem dotazu. ObjectDataSource ProductsInCategoryDataSource
v ProductsForCategoryDetails.aspx
pak získá pouze tyto produkty pro zadanou kategorii a zobrazí je v seznamu DataList, který vykreslí dva produkty na řádek. Obrázek 6 ukazuje snímek obrazovky ProductsForCategoryDetails.aspx
při prohlížení nápojů.
Obrázek 6: Zobrazí se nápoje, dva na řádek (kliknutím zobrazíte obrázek v plné velikosti)
Krok 4: Zobrazení informací o kategoriích na ProductsForCategoryDetails.aspx
Když uživatel klikne na kategorii v CategoryListMaster.aspx
nástroji , přejde na ProductsForCategoryDetails.aspx
a zobrazí produkty, které patří do vybrané kategorie. Neexistují však žádné vizuální upozornění na to, ProductsForCategoryDetails.aspx
jaká kategorie byla vybrána. Uživatel, který chtěl kliknout na Nápoje, ale omylem kliknul na Koření, nemá způsob, jak si uvědomit svou chybu, jakmile dosáhne ProductsForCategoryDetails.aspx
. Abychom tento potenciální problém zmírnili, můžeme v horní části ProductsForCategoryDetails.aspx
stránky zobrazit informace o vybrané kategorii – její název a popis.
Chcete-li toho dosáhnout, přidejte FormView nad ovládací prvek Repeater v ProductsForCategoryDetails.aspx
. Dále přidejte na stránku nový ObjectDataSource z inteligentní značky FormView s názvem CategoryDataSource
a nakonfigurujte ji tak, aby používal metodu CategoriesBLL
třídy GetCategoryByCategoryID(categoryID)
.
Obrázek 7: Přístup k informacím o kategorii prostřednictvím CategoriesBLL
metody třídy GetCategoryByCategoryID(categoryID)
(kliknutím zobrazíte obrázek v plné velikosti)
Stejně jako u objektu ProductsInCategoryDataSource
ObjectDataSource přidaného v kroku 3 CategoryDataSource
nás průvodce konfigurací zdroje dat vyzve k zadání zdroje pro GetCategoryByCategoryID(categoryID)
vstupní parametr metody. Použijte úplně stejné nastavení jako předtím a nastavte zdroj parametru na QueryString a hodnotu QueryStringField na CategoryID
(podívejte se zpět na Obrázek 5).
Po dokončení průvodce visual Studio automaticky vytvoří ItemTemplate
, EditItemTemplate
a InsertItemTemplate
pro FormView. Vzhledem k tomu, že poskytujeme rozhraní jen pro čtení, můžete odebrat EditItemTemplate
a InsertItemTemplate
. Nebojte se také přizpůsobit FormView .ItemTemplate
Po odebrání nadbytečných šablon a přizpůsobení itemTemplate by deklarativní značky FormView a ObjectDataSource měly vypadat nějak takto:
<asp:FormView ID="FormView1" runat="server" DataKeyNames="CategoryID"
DataSourceID="CategoryDataSource" EnableViewState="False" Width="100%">
<ItemTemplate>
<h3>
<asp:Label ID="CategoryNameLabel" runat="server"
Text='<%# Bind("CategoryName") %>' />
</h3>
<p>
<asp:Label ID="DescriptionLabel" runat="server"
Text='<%# Bind("Description") %>' />
</p>
</ItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="CategoryDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategoryByCategoryID" TypeName="CategoriesBLL">
<SelectParameters>
<asp:QueryStringParameter Name="categoryID" Type="Int32"
QueryStringField="CategoryID" />
</SelectParameters>
</asp:ObjectDataSource>
Obrázek 8 ukazuje snímek obrazovky při prohlížení této stránky v prohlížeči.
Poznámka
Kromě FormView jsem také přidal ovládací prvek HyperLink nad FormView, který uživatele vrátí do seznamu kategorií (CategoryListMaster.aspx
). Nebojte se umístit tento odkaz jinam nebo ho úplně vynechat.
Obrázek 8: Informace o kategoriích se teď zobrazují v horní části stránky (kliknutím zobrazíte obrázek v plné velikosti)
Krok 5: Zobrazení zprávy, pokud do vybrané kategorie nepatří žádné produkty
Stránka CategoryListMaster.aspx
obsahuje seznam všech kategorií v systému bez ohledu na to, jestli jsou k dispozici nějaké přidružené produkty. Pokud uživatel klikne na kategorii bez přidružených produktů, dataList v ProductsForCategoryDetails.aspx
souboru se nevykreslí, protože její zdroj dat nebude obsahovat žádné položky. Jak jsme viděli v minulých kurzech, GridView poskytuje EmptyDataText
vlastnost, která se dá použít k určení textové zprávy, která se má zobrazit, pokud v jeho zdroji dat nejsou žádné záznamy. DataList ani Repeater bohužel takovou vlastnost nemá.
Aby bylo možné zobrazit zprávu informující uživatele, že pro vybranou kategorii neexistují žádné odpovídající produkty, musíme na stránku přidat ovládací prvek Popisek, jehož Text
vlastnost je přiřazena k zobrazení zprávy v případě, že neexistují žádné odpovídající produkty. Pak musíme programově nastavit jeho Visible
vlastnost na základě toho, jestli DataList obsahuje nějaké položky.
Pokud to chcete udělat, začněte přidáním popisku pod DataList. Nastavte jeho ID
vlastnost na NoProductsMessage
a vlastnost Text
na "Pro vybranou kategorii neexistují žádné produkty..." Dále musíme programově nastavit vlastnost tohoto objektu Visible
Label na základě toho, jestli byla nějaká data svázaná s objektem ProductsInCategory
DataList nebo ne. Toto přiřazení musí být provedeno po svázaní dat se seznamem DataList. Pro Objekty GridView, DetailsView a FormView můžeme vytvořit obslužnou rutinu události pro událost ovládacího prvku DataBound
, která se aktivuje po dokončení datové vazby. DataList ani Repeater však nemá DataBound
událost k dispozici.
V tomto konkrétním příkladu můžeme přiřadit vlastnost Label Visible
v obslužné Page_Load
rutině události, protože data budou přiřazena k objektu DataList před událostí stránky Load
. Tento přístup by však v obecném případě nefungoval, protože data z ObjectDataSource mohou být vázána na DataList později v životním cyklu stránky. Pokud jsou například zobrazená data založena na hodnotě v jiném ovládacím prvku, například při zobrazení hlavní/podrobné sestavy pomocí DropDownList k uložení "hlavních" záznamů, data se nemusí vynořit do ovládacího prvku data web až do PreRender
fáze životního cyklu stránky.
Jedním z řešení, které bude fungovat pro všechny případy, je přiřadit Visible
vlastnost False
v obslužné rutině události DataList ItemDataBound
(nebo ItemCreated
) při vazbě položky typu Item
nebo AlternatingItem
. V takovém případě víme, že zdroj dat obsahuje alespoň jednu položku dat, a proto můžeme popisek skrýt NoProductsMessage
. Kromě této obslužné rutiny události potřebujeme také obslužnou rutinu události pro událost DataList DataBinding
, kde inicializujeme vlastnost Label Visible
do True
. Vzhledem k tomu, že událost DataBinding
se aktivuje před ItemDataBound
událostmi, vlastnost Label Visible
bude zpočátku nastavena na True
hodnotu ; Pokud však existují nějaké datové položky, bude nastavena na False
hodnotu . Následující kód implementuje tuto logiku:
protected void ProductsInCategory_DataBinding(object sender, EventArgs e)
{
// Show the Label
NoProductsMessage.Visible = true;
}
protected void ProductsInCategory_ItemDataBound(object sender, DataListItemEventArgs e)
{
// If we have a data item, hide the Label
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
NoProductsMessage.Visible = false;
}
Všechny kategorie v databázi Northwind jsou přidružené k jednomu nebo více produktům. Pro otestování této funkce jsem ručně upravil databázi Northwind pro tento kurz a znovu přiřadil všechny produkty spojené s kategorií Plodiny (CategoryID
= 7) do kategorie Mořské plody (CategoryID
= 8). To můžete provést v Průzkumníku serveru tak, že zvolíte Nový dotaz a použijete následující UPDATE
příkaz:
UPDATE Products SET
CategoryID = 8
WHERE CategoryID = 7
Po odpovídající aktualizaci databáze se vraťte na CategoryListMaster.aspx
stránku a klikněte na odkaz Vytvořit. Vzhledem k tomu, že již neexistují žádné produkty, které patří do kategorie Plodiny, měla by se zobrazit zpráva Pro vybranou kategorii neexistují žádné produkty... zpráva, jak je znázorněno na obrázku 9.
Obrázek 9: Zpráva se zobrazí, pokud do vybrané kategorie nepatří žádné produkty (kliknutím zobrazíte obrázek v plné velikosti).
Souhrn
I když sestavy hlavní a podrobné sestavy můžou zobrazit hlavní i podrobné záznamy na jedné stránce, na mnoha webech jsou rozdělené na dvě webové stránky. V tomto kurzu jsme se podívali na to, jak implementovat takovou hlavní/podrobnou sestavu tím, že kategorie jsou uvedené v seznamu s odrážkami pomocí repeateru na "hlavní" webové stránce a přidružené produkty uvedené na stránce podrobností. Každá položka seznamu na webové stránce předlohy obsahovala odkaz na stránku podrobností, která byla předána podél hodnoty řádku CategoryID
.
Na stránce podrobností bylo načtení těchto produktů pro zadaného dodavatele provedeno metodou ProductsBLL
třídy GetProductsByCategoryID(categoryID)
. Hodnota parametru categoryID
byla zadána deklarativně pomocí CategoryID
hodnoty řetězce dotazu jako zdroje parametru. Podívali jsme se také na to, jak zobrazit podrobnosti o kategorii na stránce podrobností pomocí objektu FormView a jak zobrazit zprávu, pokud do vybrané kategorie nepatří žádné produkty.
Všechno nejlepší na programování!
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ími recenzenty pro tento kurz byli Zack Jones a Liz Shulok. Chtěli byste si projít své nadcházející články na webu MSDN? Pokud ano, dejte mi řádek na mitchell@4GuysFromRolla.com.
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro