Sdílet prostřednictvím


Filtrování hlavních záznamů a podrobností na dvou stránkách pomocí ovládacího prvku Repeater a DataList (VB)

Scott Mitchell

Stáhnout PDF

V tomto kurzu se podíváme na to, jak oddělit sestavu předlohy a podrobností na dvou stránkách. Na stránce předlohy používáme ovládací prvek Repeater k vykreslení seznamu kategorií, které po kliknutí převedou uživatele na stránku "podrobnosti", kde seznam DataList se dvěma sloupci zobrazuje tyto produkty patřící do vybrané kategorie.

Úvod

V kurzu Filtrování předlohy a podrobností napříč dvěma stránkami jsme tento model prozkoumali pomocí GridView k zobrazení všech dodavatelů v systému. Toto zobrazení GridView zahrnovalo HyperLinkField, které se vykreslovaly jako odkaz na druhou stránku a předávaly se v SupplierID řetězci dotazu. Druhá stránka použila Objekt GridView k výpisu těchto produktů poskytovaných vybraným dodavatelem.

Tyto dvoustránované sestavy předlohy a podrobností lze provádět také pomocí ovládacích prvků DataList a Repeater. Jediným rozdílem je, že Ovládací prvek DataList ani Repeater neposkytuje podporu pro ovládací prvek HyperLinkField. Místo toho musíme přidat webový ovládací prvek HyperLink nebo ukotvení HTML elementu (<a>) v rámci ovládacího prvku ItemTemplate. Vlastnost Technologie 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ý pomocí ovládacího prvku Repeater zobrazí seznam kategorií v seznamu s odrážkami na jedné stránce. Každá položka seznamu bude obsahovat název a popis kategorie s názvem kategorie zobrazeným jako odkaz na druhou stránku. Kliknutím na tento odkaz uživatel přejde na druhou stránku, kde seznam 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 sestavy předlohy/podrobností je začít zobrazením záznamů "master". Prvním úkolem je proto 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 přidejte nový ObjectDataSource. Nakonfigurujte nový ObjectDataSource tak, aby přistupoval k datům z CategoriesBLL metody třídy GetCategories (viz obrázek 1).

Konfigurace ObjectDataSource pro použití Metody GetCategories třídy CategoriesBLL

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

Dále definujte šablony Repeateru tak, aby zobrazovaly názvy a popisy jednotlivých kategorií jako položky v seznamu s odrážkami. Zatím si nedělejme starosti s odkazem na každou kategorii na stránku podrobností. Následuje deklarativní kód repeateru 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 revize si projděte náš postup v prohlížeči. Jak ukazuje obrázek 2, repeater se vykreslí jako seznam s odrážkami zobrazující název a popis jednotlivých kategorií.

Každá kategorie se zobrazí jako položka seznamu s odrážkami.

Obrázek 2: Každá kategorie se zobrazí jako položka seznamu s odrážkami (kliknutím zobrazíte obrázek v plné velikosti).

Aby uživatel mohl zobrazit informace "podrobnosti" pro danou kategorii, musíme přidat odkaz na každou položku seznamu s odrážkami, která po kliknutí převeze uživatele na druhou stránku (ProductsForCategoryDetails.aspx). Tato druhá stránka pak zobrazí produkty pro vybranou kategorii pomocí prvku DataList. Abychom mohli určit kategorii, na jejíž odkaz byl kliknut, musíme prostřednictvím nějakého mechanismu předat kliknutou kategorii CategoryID na druhou stránku. Nejjednodušším, nejjednodušším způsobem, jak přenést skalární data z jedné stránky do druhé, je prostřednictvím řetězce dotazu, což je možnost, kterou použijeme v tomto kurzu. Konkrétně stránka očekává, ProductsForCategoryDetails.aspx že vybraná categoryID hodnota bude předána prostřednictvím pole řetězce dotazu s názvem CategoryID. Chcete-li například 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 webový ovládací prvek HyperLink, nebo html ukotvení element (<a>) do ItemTemplate. Ve scénářích, kde se hypertextový odkaz zobrazuje stejně pro každý řádek, bude stačit některý z přístupů. Pro Repeaters, dávám přednost použití elementu ukotvení. Pokud chcete použít element ukotvení, aktualizujte ItemTemplate Repeateru na:

<li>
    <a href='ProductsForCategoryDetails.aspx?CategoryID=<%# Eval("CategoryID") %>'>
        <%# Eval("CategoryName") %>
    </a> - <%# Eval("Description") %>
</li>

Všimněte si, že CategoryID lze vkládanou přímo do atributu elementu href ukotvení. Pokud to ale chcete provést, je nutné, aby byla hodnota atributu oddělena href apostrofy (a uvozovkami), protože Eval metoda v rámci href atributu odděluje jeho řetězec ("CategoryID") uvozovkami. Alternativně lze 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, jak se statická část adresy URL – ProductsForCategoryDetails.aspx?CategoryID – připojí k výsledku Eval("CategoryID") přímo v syntaxi vazby dat pomocí zřetězení řetězců.

Jednou z výhod použití ovládacího prvku HyperLink je to, že je možné k němu programově přistupovat z obslužné rutiny události Repeater ItemDataBound , pokud je to potřeba. Můžete například chtít zobrazit název kategorie jako text, nikoli jako odkaz pro kategorie bez přidružených produktů. Taková kontrola by mohla být provedena programově v ItemDataBound obslužné rutině události; u kategorií bez přidružených produktů by vlastnost Technologie HyperLink NavigateUrl mohla být nastavena na prázdný řetězec, což vede k tomu, že konkrétní název kategorie se vykresluje jako prostý text (nikoli jako odkaz). Další informace o formátování obsahu DataList a Repeater založeného na datech najdete v kurzu Formátování datových seznamů a repeaterů 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.aspxpředání příslušné CategoryID hodnoty (viz obrázek 3).

Názvy kategorií teď odkazují na ProductsForCategoryDetails.aspx

Obrázek 3: Odkaz ProductsForCategoryDetails.aspx Na názvy 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 objekt DataList ze sady nástrojů do Návrháře a nastavte jeho ID vlastnost na ProductsInCategory. Dále z inteligentní značky DataList zvolte přidat nový ObjectDataSource na stránku a pojmete ho ProductsInCategoryDataSource. Nakonfigurujte ji tak, aby volal metodu ProductsBLL GetProductsByCategoryID(categoryID) třídy; nastavte rozevírací seznamy na kartách INSERT, UPDATE a DELETE na (None).

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

Obrázek 4: Konfigurace 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 příležitost určit zdroj parametru. Nastavte zdroj parametrů na QueryString pomocí QueryStringField CategoryID.

Jako zdroj parametru použijte ID kategorie pole řetězce dotazu.

Obrázek 5: Použití pole CategoryID řetězce dotazu jako zdroje parametru (kliknutím zobrazíte obrázek s plnou velikostí)

Jak jsme viděli v předchozích kurzech, po dokončení průvodce Zvolit zdroj dat sada Visual Studio automaticky vytvoří seznam dat se seznamem ItemTemplate názvů a hodnot jednotlivých datových polí. Tuto šablonu nahraďte názvem produktu, dodavatelem a cenou. Vlastnost DataList RepeatColumns také nastavte na hodnotu 2. Po těchto změnách by deklarativní značky DataList a ObjectDataSource měly vypadat přibližně takto:

<asp:DataList ID="ProductsInCategory" DataKeyField="ProductID" RepeatColumns="2"
    DataSourceID="ProductsInCategoryDataSource" EnableViewState="False"
    runat="server">
    <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 s odrážkami. Provedete to tak, CategoryID že přejdete přes ProductsForCategoryDetails.aspxřetězec dotazu. Objekt ProductsInCategoryDataSource ObjectDataSource pak ProductsForCategoryDetails.aspx získá pouze ty produkty pro zadanou kategorii a zobrazí je v seznamu DataList, který vykresluje dva produkty na řádek. Obrázek 6 znázorňuje snímek obrazovky ProductsForCategoryDetails.aspx při prohlížení nápojů.

Nápoje jsou zobrazeny, dva na řádek

Obrázek 6: Zobrazí se nápoje, dvě 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.aspxoblasti , přejde do ProductsForCategoryDetails.aspx a zobrazí produkty, které patří do vybrané kategorie. V ProductsForCategoryDetails.aspx ní však nejsou žádné vizuální pomůcky k tomu, jaká kategorie byla vybrána. Uživatel, který chtěl kliknout na Nápoje, ale omylem kliknul na verze, nemá žádný způsob, jak si uvědomit svou chybu, jakmile se dostane ProductsForCategoryDetails.aspx. Abychom tento potenciální problém zmírnit, 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žívala metodu CategoriesBLL GetCategoryByCategoryID(categoryID) třídy.

Přístup k informacím o kategorii prostřednictvím metody GetCategoryByCategoryID(categoryID) třídy CategoriesBLL

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 ProductsInCategoryDataSource ObjectDataSource přidaného v kroku 3 CategoryDataSourcenás Průvodce konfigurací zdroje dat vyzve k zadání zdroje pro GetCategoryByCategoryID(categoryID) vstupní parametr metody. Použijte stejná nastavení jako předtím, nastavujte zdroj parametrů na QueryString a hodnotu CategoryID QueryStringField (odkazujte zpět na obrázek 5).

Po dokončení průvodce visual Studio automaticky vytvoří ItemTemplateEditItemTemplate, a InsertItemTemplate pro FormView. Vzhledem k tomu, že poskytujeme rozhraní jen pro čtení, můžete je odebrat EditItemTemplate a InsertItemTemplate. Také, nebojte se 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 podobně jako následující:

<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 HyperLink ovládací prvek nad FormView, který převezmou uživatele zpět do seznamu kategorií (CategoryListMaster.aspx). Nebojte se umístit tento odkaz jinam nebo vynechat úplně.

Informace o kategoriích se teď zobrazují v horní části stránky.

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 žádné produkty nepatří do vybrané kategorie

Na CategoryListMaster.aspx stránce jsou uvedeny všechny kategorie v systému bez ohledu na to, jestli existují 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 zadání textové zprávy, která se má zobrazit, pokud ve zdroji dat nejsou žádné záznamy. DataList ani Repeater bohužel takovou vlastnost nemá.

Abychom mohli zobrazit zprávu informující uživatele, že pro vybranou kategorii neexistují žádné odpovídající produkty, musíme přidat ovládací prvek Popisek na stránku, jejíž 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, zda DataList obsahuje žádné položky.

Začněte tím, že pod seznam DataList přidáte popisek. Nastavte jeho ID vlastnost na hodnotu a její Text vlastnost na NoProductsMessage hodnotu "Pro vybranou kategorii neexistují žádné produkty..." Dále musíme programově nastavit vlastnost tohoto popisku Visible na základě toho, zda byla nějaká data vázána na ProductsInCategory DataList. Toto přiřazení musí být provedeno po svázaní dat s DataList. Pro GridView, DetailsView a FormView bychom mohli vytvořit obslužnou rutinu události pro událost ovládacího prvku DataBound , která se aktivuje po dokončení vazby dat. DataList ani Repeater však nemá DataBound k dispozici událost.

V tomto konkrétním příkladu můžeme přiřadit vlastnost Popisek Visible v Page_Load obslužné rutině události, protože data budou přiřazena data DataList před událostí stránky Load . Tento přístup by ale v obecném případě nefungoval, protože data z ObjectDataSource můžou být vázaná na DataList později v životním cyklu stránky. Pokud jsou například zobrazená data založená na hodnotě jiného ovládacího prvku, například při zobrazení sestavy předlohy/podrobností pomocí rozevíracího seznamu pro uložení "master" záznamů, nemusí se data do ovládacího prvku PreRender Data Web do fáze životního cyklu stránky převést.

Jedním z řešení, které bude fungovat pro všechny případy, je přiřadit vlastnost v False obslužné rutině události DataList ItemDataBound (nebo ItemCreated) při vazbě typu Item položky nebo AlternatingItem.Visible V takovém případě víme, že ve zdroji dat existuje alespoň jedna datová položka, a proto může 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 Popisek Visible na True. Vzhledem k tomu, že se DataBinding událost aktivuje před ItemDataBound událostmi, vlastnost Label Visible bude zpočátku nastavena na True; pokud existují nějaké datové položky, bude však nastavena na False. Následující kód implementuje tuto logiku:

Protected Sub ProductsInCategory_DataBinding(sender As Object, e As EventArgs) _
    Handles ProductsInCategory.DataBinding
    'Show the Label
    NoProductsMessage.Visible = True
End Sub
 
Protected Sub ProductsInCategory_ItemDataBound(s As Object, e As DataListItemEventArgs) _
    Handles ProductsInCategory.ItemDataBound
    'If we have a data item, hide the Label
    If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = _
        ListItemType.AlternatingItem Then
 
        NoProductsMessage.Visible = False
    End If
End Sub

Všechny kategorie v databázi Northwind jsou přidružené k jednomu nebo více produktům. Pokud chcete tuto funkci otestovat, ručně jsem upravil(a) databázi Northwind pro tento kurz a znovu přiřaďte všechny produkty spojené s kategorií Plodiny (CategoryID = 7) do kategorie Mořské plody (CategoryID = 8). Toho lze dosáhnout 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 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 patřící do kategorie Plodiny, měli byste vidět položku "Pro vybranou kategorii neexistují žádné produkty...". zpráva, jak je znázorněno na obrázku 9.

Pokud neexistují žádné produkty patřící do vybrané kategorie, zobrazí se zpráva.

Obrázek 9: Zpráva se zobrazí, pokud nejsou k dispozici žádné produkty patřící do vybrané kategorie (kliknutím zobrazíte obrázek v plné velikosti).

Shrnutí

I když hlavní/podrobné sestavy můžou zobrazovat záznamy předlohy i podrobností na jedné stránce, na mnoha webech jsou oddělené na dvou webových stránkách. V tomto kurzu jsme se podívali na to, jak implementovat takovou sestavu předlohy a podrobností, protože kategorie jsou uvedené v seznamu s odrážkami pomocí repeateru na webové stránce předlohy a přidružených produktů uvedených na stránce "details". 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í, která načítá tyto produkty pro zadaného dodavatele, byla provedena metodou ProductsBLL třídy GetProductsByCategoryID(categoryID) . Hodnota categoryID parametru byla zadána deklarativní pomocí CategoryID hodnoty řetězce dotazu jako zdroje parametrů. Také jsme se podívali na to, jak zobrazit podrobnosti o kategorii na stránce podrobností pomocí FormView a jak zobrazit zprávu, pokud nebyly k dispozici žádné produkty patřící do vybrané kategorie.

Šťastné programování!

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. Vedoucí hodnotící tohoto kurzu byli Zack Jones a Liz Shulok. Chcete si projít nadcházející články MSDN? Pokud ano, zahoďte mi řádek na mitchell@4GuysFromRolla.com.