Filtrování hlavních záznamů / podrobností dvou ovládacích prvků DropDownList (C#)

Scott Mitchell

Stáhnout PDF

Tento kurz rozšiřuje vztah hlavní/podrobný o přidání třetí vrstvy pomocí dvou ovládacích prvků DropDownList k výběru požadovaných nadřazených a prarodičů záznamů.

Úvod

V předchozím kurzu jsme se zabývali tím, jak zobrazit jednoduchou sestavu master/details pomocí jednoho rozevíracího seznamu naplněného kategoriemi a objektu GridView zobrazující produkty, které patří do vybrané kategorie. Tento model sestavy funguje dobře při zobrazení záznamů, které mají relaci 1:N a dají se snadno rozšířit, aby fungovaly ve scénářích, které zahrnují více relací 1:N. Například systém zadávání objednávek by měl tabulky, které odpovídají zákazníkům, objednávkám a řádkovým položkám objednávky. Daný zákazník může mít více objednávek, přičemž každá objednávka se skládá z více položek. Taková data mohou být uživateli prezentována pomocí dvou rozevíracích seznamů a objektu GridView. První rozevírací seznam obsahuje položku seznamu pro každého zákazníka v databázi, přičemž obsahem druhého by byly objednávky zadané vybraným zákazníkem. Objekt GridView by vypisoval řádkové položky z vybrané objednávky.

I když databáze Northwind obsahuje v Customerstabulkách , Ordersa kanonické informace o zákazníkovi, objednávce a Order Details objednávce, tyto tabulky se v naší architektuře nezachycují. Přesto můžeme ilustrovat pomocí dvou závislých rozevíracích seznamů. První rozevírací seznam obsahuje seznam kategorií a druhý seznam produktů, které patří do vybrané kategorie. A DetailsView pak zobrazí seznam podrobností o vybraném produktu.

Krok 1: Vytvoření a naplnění rozevíracího seznamu kategorií

Naším prvním cílem je přidat rozevírací seznam, který uvádí kategorie. Tyto kroky byly podrobně prozkoumány v předchozím kurzu, ale jsou zde shrnuty pro úplnost.

MasterDetailsDetails.aspx Otevřete stránku ve Filtering složce, přidejte na ni rozevírací seznam, nastavte její ID vlastnost na Categoriesa potom klikněte na odkaz Konfigurovat zdroj dat v inteligentní značce. V Průvodci konfigurací zdroje dat zvolte, jestli chcete přidat nový zdroj dat.

Přidání nového zdroje dat pro rozevírací seznam

Obrázek 1: Přidání nového zdroje dat pro rozevírací seznam (kliknutím zobrazíte obrázek v plné velikosti)

Nový zdroj dat by přirozeně měl být ObjectDataSource. Pojmenujte tento nový ObjectDataSource CategoriesDataSource a nechte ho vyvolat metodu CategoriesBLL objektu GetCategories() .

Volba použití třídy CategoriesBLL

Obrázek 2: Volba použití CategoriesBLL třídy (kliknutím zobrazíte obrázek v plné velikosti)

Nakonfigurujte ObjectDataSource tak, aby používal metodu GetCategories()

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

Po nakonfigurování objektu ObjectDataSource stále musíme určit, které pole zdroje dat se má zobrazit v rozevíracím Categories seznamu a které z nich má být nakonfigurováno jako hodnota položky seznamu. CategoryName Nastavte pole jako zobrazení a CategoryID jako hodnotu pro každou položku seznamu.

Nechte v rozevíracím seznamu zobrazit pole CategoryName a jako hodnotu použijte CategoryID.

Obrázek 4: Nechte rozevírací seznam zobrazit CategoryName pole a použít CategoryID jako hodnotu (kliknutím zobrazíte obrázek v plné velikosti).

V tomto okamžiku máme ovládací prvek DropDownList (Categories), který se naplní záznamy z Categories tabulky. Když si uživatel vybere novou kategorii z rozevíracího seznamu, budeme chtít, aby došlo k zpětnému odeslání, aby se aktualizoval produkt DropDownList, který vytvoříme v kroku 2. Proto zaškrtněte možnost Enable AutoPostBack (Povolit AutoPostBack) categories z inteligentní značky DropDownList.

Povolení funkce AutoPostBack pro rozevírací seznam kategorií

Obrázek 5: Povolení funkce AutoPostBack pro Categories rozevírací seznam (kliknutím zobrazíte obrázek v plné velikosti)

Krok 2: Zobrazení produktů vybrané kategorie ve druhém rozevíracím seznamu

Categories Po dokončení dropDownList je naším dalším krokem zobrazení rozevíracího seznamu produktů, které patří do vybrané kategorie. Dosáhnete toho tak, že na stránku přidáte další rozevírací seznam s názvem ProductsByCategory. Stejně jako u rozevíracího Categories seznamu vytvořte nový ObjectDataSource pro ProductsByCategory rozevírací seznam s názvem ProductsByCategoryDataSource.

Přidání nového zdroje dat pro rozevírací seznam ProductsByCategory

Obrázek 6: Přidání nového zdroje dat pro ProductsByCategory rozevírací seznam (kliknutím zobrazíte obrázek v plné velikosti)

Vytvoření nového objektuDataSource s názvem ProductsByCategoryDataSource

Obrázek 7: Vytvoření nového objektuDataSource s názvem ProductsByCategoryDataSource (kliknutím zobrazíte obrázek v plné velikosti)

Vzhledem k tomu, ProductsByCategory že DropDownList potřebuje zobrazit pouze ty produkty, které patří do vybrané kategorie, nechte ObjectDataSource vyvolat metodu GetProductsByCategoryID(categoryID) z objektu ProductsBLL .

Snímek obrazovky s oknem Konfigurovat zdroj dat – productsByCategoryDataSource s vybranou možností ProductsBLL a zvýrazněným tlačítkem Další

Obrázek 8: Volba použití ProductsBLL třídy (kliknutím zobrazíte obrázek v plné velikosti)

Konfigurace objektu ObjectDataSource na použití metody GetProductsByCategoryID(categoryID)

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

V posledním kroku průvodce musíme zadat hodnotu parametru categoryID . Přiřaďte tento parametr vybrané položce z rozevíracího Categories seznamu.

Načtení hodnoty parametru categoryID z rozevíracího seznamu kategorií

Obrázek 10: Načtení hodnoty parametru categoryID z rozevíracího Categories seznamu (kliknutím zobrazíte obrázek v plné velikosti)

Když je objekt ObjectDataSource nakonfigurovaný, zbývá jen určit, která pole zdroje dat se použijí pro zobrazení a hodnotu položek DropDownList. ProductName Zobrazte pole a použijte ho ProductID jako hodnotu.

Zadejte pole zdroje dat použitá pro vlastnosti textových a hodnot objektu ListItems položky DropDownList.

Obrázek 11: Určení polí zdroje dat použitých pro vlastnosti a Value vlastnosti rozevíracího ListItemText seznamu (kliknutím zobrazíte obrázek v plné velikosti).

S nakonfigurovanými objekty ObjectDataSource a ProductsByCategory DropDownList se na naší stránce zobrazí dva rozevírací seznamy: první bude zobrazovat všechny kategorie, zatímco druhá bude seznam produktů, které patří do vybrané kategorie. Když uživatel vybere novou kategorii z prvního DropDownList, vytvoří se postback a druhý dropDownList se vrátí a zobrazí produkty, které patří do nově vybrané kategorie. Obrázky 12 a 13 se zobrazují MasterDetailsDetails.aspx v akci při prohlížení prostřednictvím prohlížeče.

Při první návštěvě stránky se vybere kategorie Nápoje.

Obrázek 12: Při první návštěvě stránky je vybrána kategorie Nápoje (kliknutím zobrazíte obrázek v plné velikosti)

Při výběru jiné kategorie se zobrazí produkty nové kategorie.

Obrázek 13: Volba jiné kategorie zobrazí produkty nové kategorie (kliknutím zobrazíte obrázek v plné velikosti).

productsByCategory V současné době DropDownList, při změně, nezpůsobuje postback. Budeme však chtít, aby došlo k zpětnému odeslání, jakmile přidáme DetailsView pro zobrazení podrobností o vybraném produktu (krok 3). Proto zaškrtněte políčko Enable AutoPostBack z productsByCategory inteligentní značky DropDownList.

Povolení funkce AutoPostBack pro rozevírací seznam productsByCategory

Obrázek 14: Povolení funkce AutoPostBack pro productsByCategory rozevírací seznam (kliknutím zobrazíte obrázek v plné velikosti)

Krok 3: Zobrazení podrobností vybraného produktu pomocí prvku DetailsView

Posledním krokem je zobrazení podrobností o vybraném produktu v zobrazení DetailsView. Chcete-li toho dosáhnout, přidejte DetailsView na stránku, nastavte jeho ID vlastnost na ProductDetailsa vytvořte pro něj nový ObjectDataSource. Nakonfigurujte tento ObjectDataSource tak, aby načítá data z ProductsBLL metody třídy GetProductByProductID(productID) pomocí vybrané hodnoty ProductsByCategory DropDownList pro hodnotu parametru productID .

Snímek obrazovky s oknem Konfigurovat zdroj dat – productsByCategoryDataSource, kde je vybraná možnost ProductsBLL a zvýrazněné tlačítko Další

Obrázek 15: Volba použití ProductsBLL třídy (kliknutím zobrazíte obrázek v plné velikosti)

Konfigurace objektu ObjectDataSource na použití metody GetProductByProductID(productID)

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

Vytáhněte hodnotu parametru productID z rozevíracího seznamu ProductsByCategory.

Obrázek 17: Načtení hodnoty parametru productID z rozevíracího ProductsByCategory seznamu (kliknutím zobrazíte obrázek v plné velikosti)

Můžete zvolit zobrazení libovolného z dostupných polí v zobrazení DetailsView. Rozhodl(a) jsem se odebrat ProductIDpole , SupplierIDa CategoryID a přeuspořádal(a) jsem zbývající pole a naformátoval(a). Kromě toho jsem vymazal DetailsView HeightWidth a vlastnosti, což umožňuje DetailsView rozšířit na šířku potřebnou k tomu, aby se data co nejlépe zobrazovala, místo aby byla omezena na zadanou velikost. Úplný kód se zobrazí níže:

<asp:DetailsView ID="ProductDetails" runat="server"
    AutoGenerateRows="False" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" EnableViewState="False">
    <Fields>
        <asp:BoundField DataField="ProductName"
          HeaderText="Product" SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName"
          HeaderText="Category" ReadOnly="True"
          SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName"
          HeaderText="Supplier" ReadOnly="True"
          SortExpression="SupplierName" />
        <asp:BoundField DataField="QuantityPerUnit"
          HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
        <asp:BoundField DataField="UnitPrice"
          DataFormatString="{0:c}" HeaderText="Price"
          HtmlEncode="False" SortExpression="UnitPrice" />
        <asp:BoundField DataField="UnitsInStock"
          HeaderText="UnitsInStock" SortExpression="Units In Stock" />
        <asp:BoundField DataField="UnitsOnOrder"
          HeaderText="UnitsOnOrder" SortExpression="Units On Order" />
        <asp:BoundField DataField="ReorderLevel"
          HeaderText="ReorderLevel" SortExpression="Reorder Level" />
        <asp:CheckBoxField DataField="Discontinued"
          HeaderText="Discontinued" SortExpression="Discontinued" />
    </Fields>
</asp:DetailsView>

Chvíli si stránku vyzkoušejte MasterDetailsDetails.aspx v prohlížeči. Na první pohled se může zdát, že všechno funguje podle potřeby, ale je tu drobný problém. Když zvolíte novou kategorii ProductsByCategory , rozevírací seznam se aktualizuje tak, aby zahrnoval produkty pro vybranou kategorii, ale ProductDetails DetailsView dál zobrazuje předchozí informace o produktu. DetailsView se aktualizuje při výběru jiného produktu pro vybranou kategorii. Kromě toho, pokud budete dostatečně důkladně testovat, zjistíte, že pokud budete neustále vybírat nové kategorie (například zvolíte Nápoje z rozevíracího Categories seznamu, pak Condiments a pak Confections), každý druhý výběr kategorie způsobí ProductDetails , že DetailsView se aktualizuje.

Abychom mohli tento problém zkonkretizovat, podívejme se na konkrétní příklad. Při první návštěvě stránky se vybere kategorie Nápoje a související produkty se načtou do rozevíracího ProductsByCategory seznamu. Chai je vybraný produkt a jeho podrobnosti se zobrazují v ProductDetails zobrazení DetailsView, jak je znázorněno na obrázku 18.

Podrobnosti vybraného produktu se zobrazí v zobrazení DetailsView.

Obrázek 18: Podrobnosti vybraného produktu se zobrazí v zobrazení DetailsView (kliknutím zobrazíte obrázek v plné velikosti).

Pokud změníte výběr kategorie z Nápoje na Condiments, dojde k zpětnému odeslání a ProductsByCategory dropDownList se odpovídajícím způsobem aktualizuje, ale zobrazení DetailsView stále zobrazuje podrobnosti o Chai.

Podrobnosti o dříve vybraném produktu se stále zobrazují.

Obrázek 19: Podrobnosti o dříve vybraném produktu se stále zobrazují (kliknutím zobrazíte obrázek v plné velikosti).

Výběrem nového produktu ze seznamu se zobrazení DetailsView aktualizuje podle očekávání. Pokud po změně produktu vyberete novou kategorii, zobrazení DetailsView se znovu neaktualizuje. Pokud jste ale místo výběru nového produktu vybrali novou kategorii, zobrazení DetailsView by se aktualizovalo. Co se tady děje na světě?

Problém je problém s načasováním v životním cyklu stránky. Pokaždé, když je stránka požadována, prochází při vykreslování několika kroky. V jednom z těchto kroků ovládací prvky ObjectDataSource zkontrolují, jestli se některé z jejich SelectParameters hodnot nezměnily. Pokud ano, datový web ovládací prvek svázaný s ObjectDataSource ví, že potřebuje aktualizovat své zobrazení. Když je například vybrána nová kategorie, ObjectDataSource zjistí, ProductsByCategoryDataSource že se hodnoty parametrů změnily, a ProductsByCategory DropDownList se znovu připojí a získá produkty pro vybranou kategorii.

Problém, který vznikne v této situaci, spočívá v tom, že bod v životním cyklu stránky, který ObjectDataSources kontroluje pro změněné parametry, nastane před změnou vazby přidružených datových webových ovládacích prvků. Proto při výběru nové kategorie ProductsByCategoryDataSource ObjectDataSource zjistí změnu v hodnotě svého parametru. ObjectDataSource, který ProductDetails používá DetailsView, ale žádné takové změny nezaznamená, protože ProductsByCategory rozevírací seznam musí být ještě znovu doskok. Později v průběhu životního cyklu ProductsByCategory dropDownList znovu přidružuje svůj ObjectDataSource a vezme produkty pro nově vybranou kategorii. ProductsByCategory Zatímco hodnota DropDownList se změnila, ProductDetails ObjectDataSource DetailsView již provedl kontrolu hodnoty parametru, a proto DetailsView zobrazí předchozí výsledky. Tato interakce je znázorněna na obrázku 20.

Hodnota rozevíracího seznamu ProductsByCategory se změní po kontrole změn objektu ObjectDataSource objektu ProductDetails DetailsView.

Obrázek 20: Hodnota ProductsByCategory DropDownList se změní po kontrole změn ObjectDataSource objektu ProductDetails DetailsView (kliknutím zobrazíte obrázek v plné velikosti)

Abychom tento problém odstranili, musíme explicitně znovu vytvořit vazbu ProductDetails DetailsView po vázání rozevíracího ProductsByCategory seznamu. Toho můžeme dosáhnout voláním ProductDetails metody DetailsView DataBind() při ProductsByCategory spuštění události DropDownList DataBound . Přidejte následující kód obslužné rutiny události do MasterDetailsDetails.aspx třídy kódu na pozadí stránky (projděte si téma "Programově nastavení hodnot parametrů ObjectDataSource" pro diskuzi o tom, jak přidat obslužnou rutinu události):

protected void ProductsByCategory_DataBound(object sender, EventArgs e)
{
    ProductDetails.DataBind();
}

Po přidání tohoto explicitního ProductDetails volání metody DetailsView DataBind() kurz funguje podle očekávání. Obrázek 21 ukazuje, jak tato změna vyřešila náš dřívější problém.

Zobrazení Podrobností ProductDetails je explicitně aktualizováno, když se aktivuje událost DataBound v rozevíracím seznamu ProductsByCategory.

Obrázek 21: Zobrazení ProductDetails DetailsView se explicitně aktualizuje při ProductsByCategory vyvolání události rozevíracího DataBound seznamu (kliknutím zobrazíte obrázek v plné velikosti)

Souhrn

DropDownList slouží jako ideální prvek uživatelského rozhraní pro hlavní a podrobné sestavy, kde existuje vztah 1:N mezi hlavním a podrobným záznamem. V předchozím kurzu jsme viděli, jak pomocí jednoho rozevíracího seznamu filtrovat produkty zobrazené podle vybrané kategorie. V tomto kurzu jsme nahradili GridView produktů rozevíracím seznamem a použili jsme DetailsView k zobrazení podrobností o vybraném produktu. Koncepty probírané v tomto kurzu lze snadno rozšířit na datové modely zahrnující více relací 1:N, jako jsou zákazníci, objednávky a položky objednávek. Obecně můžete vždy přidat rozevírací seznam pro každou entitu "1" v relacích 1:N.

Šťastné 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 najít na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na http://ScottOnWriting.NETadrese .

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 Hilton Giesenow. Chcete si projít moje nadcházející články na WEBU MSDN? Pokud ano, dejte mi čáru na mitchell@4GuysFromRolla.comadresu .