Zobrazení hlavních záznamů / podrobností v seznamu hlavních záznamů s odrážkami a podrobnostmi v prvku DataList (C#)
Scott Mitchell
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).
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 CategoryProducts
hodnotu . 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).
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ímProductsBLL
metody třídyGetProductsByCategoryID(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 rutinuItemDataBound
události, která pro každou kategorii vázanou na Repeater volá metoduProductsBLL
třídyGetProductsByCategoryID(categoryID)
a zahrnuje její počet ve výstupu. CategoriesDataTable
Aktualizujte typovou datovou sadu tak, aby zahrnovalaNumberOfProducts
sloupec. Pak můžeme aktualizovat metoduGetCategories()
CategoriesDataTable
tak, aby zahrnovala tyto informace, nebo případně ponechatGetCategories()
tak, jak je, a vytvořit novouCategoriesDataTable
metodu volanouGetCategoriesAndNumberOfProducts()
.
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()
.
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č ItemCommand
se 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).
Obrázek 4: Zobrazí se název každé kategorie a počet produktů (kliknutím zobrazíte obrázek v plné velikosti).
CategoriesDataTable
Aktualizace aCategoriesTableAdapter
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
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)
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.
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.
Obrázek 7: Vytvoření metody pomocí ad hoc příkazu SQL (kliknutím zobrazíte obrázek s plnou velikostí)
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
, CategoryName
a 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
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í).
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).
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é).
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.
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:
CommandName
Nastavte vlastnost LinkButton v Repeater sItemTemplate
na určitou hodnotu (používám ListProducts ). Nastavením tétoCommandName
hodnoty se událost LinkButton sCommand
aktivuje při kliknutí na tlačítko LinkButton.- Nastavte vlastnost LinkButton na
CommandArgument
hodnotu aktuální položky sCategoryID
. - Vytvořte obslužnou rutinu události pro událost Repeater s
ItemCommand
. V obslužné rutině události nastavteCategoryProductsDataSource
ObjectDataSource sCategoryID
parametr na hodnotu předanéhoCommandArgument
.
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).
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).
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í:
- Floatutorial kurz o plovoucích elementech CSS pomocí CSS
- Umístění dalších informací o umístění prvků pomocí šablon stylů CSS
- Rozložení obsahu pomocí HTML a
<table>
dalších prvků HTML pro umístě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. 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.
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