Sdílet prostřednictvím


Řazení dat sestavy ovládacími prvky DataList nebo Repeater (C#)

Scott Mitchell

Stáhnout PDF

V tomto kurzu se podíváme, jak zahrnout podporu řazení do datových seznamů a opakovačů a jak vytvořit DataList nebo Repeater, jejichž data se dají stránkovat a seřadit.

Úvod

V předchozím kurzu jsme prozkoumali, jak přidat podporu stránkování do seznamu DataList. Vytvořili jsme novou metodu ProductsBLL ve třídě (GetProductsAsPagedDataSource), která vrátila PagedDataSource objekt. Při vazbě na datalist nebo repeater by se v sadě DataList nebo Repeater zobrazila jenom požadovaná stránka dat. Tato technika je podobná tomu, co interně používají ovládací prvky GridView, DetailsView a FormView k poskytování jejich integrované výchozí funkce stránkování.

Kromě podpory stránkování zahrnuje GridView také podporu řazení. Ani DataList ani Repeater poskytují integrované funkce řazení; Funkce řazení však mohou být přidány s trochou kódu. V tomto kurzu se podíváme, jak zahrnout podporu řazení do datových seznamů a opakovačů a jak vytvořit DataList nebo Repeater, jejichž data se dají stránkovat a seřadit.

Kontrola řazení

Jak jsme viděli v kurzu Stránkování a řazení dat sestavy , ovládací prvek GridView poskytuje podporu řazení. Každé pole GridView může mít přidružený SortExpressionobjekt , který označuje datové pole, podle kterého se mají data seřadit. Když GridView s AllowSorting vlastnost je nastavena na true, každé GridView pole, které má SortExpression hodnotu vlastnosti má jeho záhlaví vykresleno jako LinkButton. Když uživatel klikne na konkrétní záhlaví pole GridView s, dojde k zpětnému odeslání a data se seřadí podle klepaného pole s SortExpression.

Ovládací prvek GridView má SortExpression také vlastnost, která ukládá SortExpression pole GridView, podle kterého jsou data seřazena. Vlastnost navíc označuje, SortDirection jestli mají být data seřazena vzestupně nebo sestupně (pokud uživatel klikne dvakrát po sobě na odkaz záhlaví konkrétního pole GridView, pořadí řazení se přepne).

Když je Objekt GridView vázán na svůj ovládací prvek zdroje dat, předá své SortExpression vlastnosti a SortDirection ovládacímu prvku zdroje dat. Ovládací prvek zdroje dat načte data a pak je seřadí podle zadaných SortExpression vlastností a SortDirection vlastností. Po seřazení dat je ovládací prvek zdroje dat vrátí do objektu GridView.

Abychom mohli replikovat tuto funkci pomocí ovládacích prvků DataList nebo Repeater, musíme:

  • Vytvoření rozhraní pro řazení
  • Zapamatujte si datové pole, podle které se má řadit, a zda se má řadit vzestupně nebo sestupně.
  • Dát objektu ObjectDataSource pokyn, aby data seřadil podle konkrétního datového pole.

Tyto tři úkoly budeme řešit v krocích 3 a 4. Potom prozkoumáme, jak zahrnout podporu stránkování i řazení do datalistu nebo repeateru.

Krok 2: Zobrazení produktů v opakovači

Než se začneme zabývat implementací jakékoli funkce související s řazením, začněme výpisem produktů v ovládacím prvku Repeater. Začněte otevřením Sorting.aspx stránky ve PagingSortingDataListRepeater složce. Přidejte na webovou stránku ovládací prvek Repeater a nastavte jeho ID vlastnost na SortableProducts. Z inteligentní značky Repeater s vytvořte nový ObjectDataSource s názvem ProductsDataSource a nakonfigurujte ho ProductsBLL tak, aby načítal data z metody třídy s GetProducts() . V rozevíracích seznamech na kartách INSERT, UPDATE a DELETE vyberte možnost (Žádné).

Vytvořte ObjectDataSource a nakonfigurujte ho tak, aby používal metodu GetProductsAsPagedDataSource().

Obrázek 1: Vytvoření objektu ObjectDataSource a jeho konfigurace pro použití GetProductsAsPagedDataSource() metody (kliknutím zobrazíte obrázek v plné velikosti)

Nastavte Drop-Down Seznamy na kartách UPDATE, INSERT a DELETE na (Žádné).

Obrázek 2: Nastavte Drop-Down Seznamy na kartách UPDATE, INSERT a DELETE na (Žádné) (Kliknutím zobrazíte obrázek v plné velikosti)

Na rozdíl od DataList, Visual Studio nevytvoří ItemTemplate automaticky pro ovládací prvek Repeater po jeho vazbě ke zdroji dat. Navíc to musíme přidat ItemTemplate deklarativně, protože inteligentní značka ovládacího prvku Repeater s chybí možnost Upravit šablony, která se nachází v sadě DataList s. Pojďme použít to samé ItemTemplate z předchozího kurzu, který zobrazil název produktu, dodavatele a kategorii.

Po přidání deklarativní značky ItemTemplateRepeater a ObjectDataSource by měly vypadat přibližně takto:

<asp:Repeater ID="SortableProducts" DataSourceID="ProductsDataSource"
    EnableViewState="False" runat="server">
    <ItemTemplate>
        <h4><asp:Label ID="ProductNameLabel" runat="server"
            Text='<%# Eval("ProductName") %>'></asp:Label></h4>
        Category:
        <asp:Label ID="CategoryNameLabel" runat="server"
            Text='<%# Eval("CategoryName") %>'></asp:Label><br />
        Supplier:
        <asp:Label ID="SupplierNameLabel" runat="server"
            Text='<%# Eval("SupplierName") %>'></asp:Label><br />
        <br />
        <br />
    </ItemTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
    SelectMethod="GetProducts">
</asp:ObjectDataSource>

Obrázek 3 ukazuje tuto stránku při zobrazení v prohlížeči.

Zobrazí se název, dodavatel a kategorie jednotlivých produktů.

Obrázek 3: Zobrazí se název každého produktu, dodavatel a kategorie (kliknutím zobrazíte obrázek v plné velikosti)

Krok 3: Pokyn objektu ObjectDataSource k seřazení dat

Pokud chcete seřadit data zobrazená v repeateru, musíme informovat ObjectDataSource o výrazu řazení, podle kterého se mají data seřadit. Než ObjectDataSource načte svá data, nejprve aktivuje svou Selecting událost, což nám umožňuje zadat výraz řazení. Obslužné Selecting rutině události je předán objekt typu ObjectDataSourceSelectingEventArgs, který má vlastnost s názvem Arguments typu DataSourceSelectArguments. Třída DataSourceSelectArguments je navržena tak, aby předávala požadavky související s daty od příjemce dat do ovládacího prvku zdroje dat a obsahuje SortExpression vlastnost.

Pokud chcete předat informace o řazení ze stránky ASP.NET do ObjectDataSource, vytvořte obslužnou rutinu Selecting události pro událost a použijte následující kód:

protected void ProductsDataSource_Selecting
    (object sender, ObjectDataSourceSelectingEventArgs e)
{
    e.Arguments.SortExpression = sortExpression;
}

Hodnota sortExpression by měla mít přiřazený název datového pole pro řazení dat (například ProductName). Neexistuje žádná vlastnost související se směrem řazení, takže pokud chcete data seřadit sestupně, připojte řetězec DESC k hodnotě sortExpression (například ProductName DESC).

Pokračujte a vyzkoušejte několik různých pevně zakódovaných hodnot pro sortExpression a otestujte výsledky v prohlížeči. Jak ukazuje obrázek 4, při použití ProductName DESC jako sortExpression jsou produkty seřazeny podle jejich názvu v obráceném abecedním pořadí.

Produkty jsou seřazeny podle názvu v obráceném abecedním pořadí.

Obrázek 4: Produkty jsou seřazeny podle názvu v obráceném abecedním pořadí (kliknutím zobrazíte obrázek v plné velikosti)

Krok 4: Vytvoření rozhraní pro řazení a zapamatování výrazu a směru řazení

Zapnutí podpory řazení v zobrazení GridView převede každý text záhlaví seřaditelných polí na tlačítko LinkButton, které po kliknutí seřadí data odpovídajícím způsobem. Takové rozhraní pro řazení dává smysl pro GridView, kde jsou jeho data úhledně rozložena ve sloupcích. Pro ovládací prvky DataList a Repeater je však potřeba jiné rozhraní pro řazení. Běžným rozhraním pro řazení seznamu dat (na rozdíl od mřížky dat) je rozevírací seznam, který poskytuje pole, podle kterých lze data seřadit. Pojďme implementovat takové rozhraní pro tento kurz.

Přidejte ovládací prvek DropDownList Web nad SortableProducts Repeater a nastavte jeho ID vlastnost na SortBy. V okno Vlastnosti kliknutím na tři tečky ve Items vlastnosti zobrazte Editor Kolekce ListItem. Přidáním ListItem s seřadíte data podle ProductNamepolí , CategoryNamea SupplierName . Přidejte také a ListItem seřadíte produkty podle jejich názvu v obráceném abecedním pořadí.

Vlastnosti ListItemText lze nastavit na libovolnou hodnotu (například Název), ale Value vlastnosti musí být nastaveny na název datového pole (například ProductName ). Pokud chcete výsledky seřadit sestupně, připojte k názvu datového pole řetězec DESC, například ProductName DESC .

Přidání položky ListItem pro jednotlivá datová pole s možností řazení

Obrázek 5: Přidání ListItem pro každé z datových polí s možností řazení

Nakonec přidejte ovládací prvek Web button napravo od rozevíracího seznamu. Nastavte jeho ID hodnotu do RefreshRepeater a jeho Text vlastnost na Aktualizovat .

Po vytvoření ListItem s a přidání tlačítka Aktualizovat by deklarativní syntaxe DropDownList a Button s měla vypadat nějak takto:

<asp:DropDownList ID="SortBy" runat="server">
    <asp:ListItem Value="ProductName">Name</asp:ListItem>
    <asp:ListItem Value="ProductName DESC">Name (Reverse Order)
        </asp:ListItem>
    <asp:ListItem Value="CategoryName">Category</asp:ListItem>
    <asp:ListItem Value="SupplierName">Supplier</asp:ListItem>
</asp:DropDownList>
<asp:Button runat="server" ID="RefreshRepeater" Text="Refresh" />

Po dokončení řazení DropDownList musíme dále aktualizovat obslužnou rutinu události ObjectDataSource s Selecting tak, aby používala vybranou SortBy``ListItem vlastnost s Value místo pevně zakódovaného výrazu řazení.

protected void ProductsDataSource_Selecting
    (object sender, ObjectDataSourceSelectingEventArgs e)
{
    // Have the ObjectDataSource sort the results by the selected
    // sort expression
    e.Arguments.SortExpression = SortBy.SelectedValue;
}

V tomto okamžiku při první návštěvě stránky budou produkty zpočátku seřazeny podle datového ProductName pole, protože je SortByListItem ve výchozím nastavení vybrané (viz obrázek 6). Když vyberete jinou možnost řazení, například Kategorie, a kliknete na Aktualizovat, dojde k zpětnému odeslání a opětovnému seřazení dat podle názvu kategorie, jak je znázorněno na obrázku 7.

Produkty jsou původně seřazeny podle názvu.

Obrázek 6: Produkty jsou zpočátku seřazené podle názvu (kliknutím zobrazíte obrázek v plné velikosti)

Produkty jsou nyní seřazeny podle kategorie.

Obrázek 7: Produkty jsou nyní seřazené podle kategorie (kliknutím zobrazíte obrázek v plné velikosti)

Poznámka

Kliknutí na tlačítko Aktualizovat způsobí, že data se automaticky znovu seřadí, protože stav zobrazení Repeater s byl zakázán, což způsobí, že repeater se při každém zpětném odeslání znovu přidruží ke svému zdroji dat. Pokud jste nechali stav zobrazení Repeater zapnutý, změna rozevíracího seznamu řazení nebude mít na pořadí řazení žádný vliv. Chcete-li tento problém vyřešit, vytvořte obslužnou rutinu události pro událost Aktualizovat tlačítko s Click a znovu připojí repeater ke zdroji dat (voláním metody Repeater s DataBind() ).

Zapamatování výrazu a směru řazení

Při vytváření seřaditelného datalistu nebo repeateru na stránce, kde může docházet k neseřazeným zpětným zpětnému odeslání, je nezbytné, aby se výraz a směr řazení pamatoval napříč postbacky. Představte si například, že jsme v tomto kurzu aktualizovali opakovač tak, aby u každého produktu obsahoval tlačítko Odstranit. Když uživatel klikne na tlačítko Odstranit, spustíme nějaký kód pro odstranění vybraného produktu a pak znovu připojíme data k repeateru. Pokud se podrobnosti o řazení v rámci postbacku neuchovávají, data zobrazená na obrazovce se vrátí k původnímu pořadí řazení.

Pro účely tohoto kurzu dropDownList implicitně ukládá výraz a směr řazení ve stavu zobrazení. Kdybychom používali jiné rozhraní pro řazení, například s linkbuttony, které poskytovaly různé možnosti řazení, museli bychom se postarat o zapamatování pořadí řazení napříč postbacky. Toho lze dosáhnout uložením parametrů řazení do stavu zobrazení stránky, zahrnutím parametru řazení do řetězce dotazu nebo pomocí jiné techniky trvalosti stavu.

Budoucí příklady v tomto kurzu se dozvíte, jak zachovat podrobnosti řazení ve stavu zobrazení stránky.

Krok 5: Přidání podpory řazení do seznamu DataList, který používá výchozí stránkování

V předchozím kurzu jsme prozkoumali, jak implementovat výchozí stránkování pomocí DataListu. Pojďme tento předchozí příklad rozšířit o možnost řazení stránkovaných dat. Začněte otevřením SortingWithDefaultPaging.aspx stránek a Paging.aspx ve PagingSortingDataListRepeater složce . Paging.aspx Kliknutím na tlačítko Zdroj na stránce zobrazte deklarativní kód stránky. Zkopírujte vybraný text (viz Obrázek 8) a vložte ho do deklarativního kódu SortingWithDefaultPaging.aspx mezi <asp:Content> značky.

Replikace deklarativních značek <asp:Content> z Paging.aspx do SortingWithDefaultPaging.aspx

Obrázek 8: Replikace deklarativního kódu ve <asp:Content> značkách do Paging.aspxSortingWithDefaultPaging.aspx (kliknutím zobrazíte obrázek v plné velikosti)

Po zkopírování deklarativního kódu zkopírujte metody a vlastnosti ve Paging.aspx třídě kódu na pozadí stránky do třídy kódu na pozadí pro SortingWithDefaultPaging.aspx. Teď se na chvíli podívejte na SortingWithDefaultPaging.aspx stránku v prohlížeči. Měl by mít stejnou funkčnost a vzhled jako Paging.aspx.

Rozšíření ProductsBLL o zahrnutí výchozí metody stránkování a řazení

V předchozím kurzu jsme ve třídě vytvořili metodu GetProductsAsPagedDataSource(pageIndex, pageSize)ProductsBLL , která vrátila PagedDataSource objekt. Tento PagedDataSource objekt byl naplněn všemi produkty (prostřednictvím metody BLL s GetProducts() ), ale při vazbě na DataList byly zobrazeny pouze záznamy odpovídající zadaným vstupním parametrům pageIndex a pageSize .

Dříve v tomto kurzu jsme přidali podporu řazení zadáním výrazu řazení z obslužné rutiny události ObjectDataSource Selecting . To funguje dobře, když ObjectDataSource je vrácen objekt, který lze seřadit, jako je ProductsDataTable vrácený metodou GetProducts() . Objekt vrácený PagedDataSource metodou GetProductsAsPagedDataSource však nepodporuje řazení vnitřního zdroje dat. Místo toho musíme výsledky vrácené metodou GetProducts()seřadit před tím, než ji vložíme do PagedDataSource.

Chcete-li toho dosáhnout, vytvořte novou metodu ProductsBLL ve třídě GetProductsSortedAsPagedDataSource(sortExpression, pageIndex, pageSize). Pokud chcete seřadit ProductsDataTable objekt vrácený metodou GetProducts() , zadejte Sort vlastnost jeho výchozí DataTableViewhodnoty :

[System.ComponentModel.DataObjectMethodAttribute
    (System.ComponentModel.DataObjectMethodType.Select, false)]
public PagedDataSource GetProductsSortedAsPagedDataSource
    (string sortExpression, int pageIndex, int pageSize)
{
    // Get ALL of the products
    Northwind.ProductsDataTable products = GetProducts();
    // Sort the products
    products.DefaultView.Sort = sortExpression;
    // Limit the results through a PagedDataSource
    PagedDataSource pagedData = new PagedDataSource();
    pagedData.DataSource = products.DefaultView;
    pagedData.AllowPaging = true;
    pagedData.CurrentPageIndex = pageIndex;
    pagedData.PageSize = pageSize;
    return pagedData;
}

Metoda se GetProductsSortedAsPagedDataSource jen mírně liší od GetProductsAsPagedDataSource metody vytvořené v předchozím kurzu. Konkrétně GetProductsSortedAsPagedDataSource akceptuje další vstupní parametr sortExpression a přiřadí tuto hodnotu vlastnosti SortProductDataTable s DefaultView. O několik řádků kódu později se objektu PagedDataSource s DataSource přiřadí ProductDataTable s DefaultView.

Volání metody GetProductsSortedAsPagedDataSource a zadání hodnoty pro vstupní parametr SortExpression

GetProductsSortedAsPagedDataSource Po dokončení metody je dalším krokem zadání hodnoty tohoto parametru. ObjectDataSource v je SortingWithDefaultPaging.aspx aktuálně nakonfigurována pro volání GetProductsAsPagedDataSource metody a předává dva vstupní parametry prostřednictvím svých dvou QueryStringParameters, které jsou zadány v kolekci SelectParameters . Tyto dvě QueryStringParameters značí, že zdroj parametrů GetProductsAsPagedDataSourcemetody pageIndex a pageSize pochází z polí pageIndex řetězce dotazu a pageSize.

Aktualizujte vlastnost ObjectDataSource tak SelectMethod , aby vyvolala novou GetProductsSortedAsPagedDataSource metodu. Pak přidejte nový QueryStringParameter parametr, aby se ke vstupnímu parametru sortExpression přistupovalo z pole sortExpressionřetězce dotazu . Nastavte QueryStringParameter s DefaultValue na ProductName .

Po těchto změnách by deklarativní kód ObjectDataSource měl vypadat takto:

<asp:ObjectDataSource ID="ProductsDefaultPagingDataSource"
    OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
    SelectMethod="GetProductsSortedAsPagedDataSource"
    OnSelected="ProductsDefaultPagingDataSource_Selected" runat="server">
    <SelectParameters>
        <asp:QueryStringParameter DefaultValue="ProductName"
            Name="sortExpression" QueryStringField="sortExpression"
            Type="String" />
        <asp:QueryStringParameter DefaultValue="0" Name="pageIndex"
            QueryStringField="pageIndex" Type="Int32" />
        <asp:QueryStringParameter DefaultValue="4" Name="pageSize"
            QueryStringField="pageSize" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

V tomto okamžiku SortingWithDefaultPaging.aspx stránka seřadí výsledky abecedně podle názvu produktu (viz Obrázek 9). Je to proto, že ve výchozím nastavení je hodnota ProductName předána jako GetProductsSortedAsPagedDataSource metoda s sortExpression parametr.

Ve výchozím nastavení jsou výsledky seřazené podle ProductName.

Obrázek 9: Ve výchozím nastavení jsou výsledky seřazené podle ProductName (kliknutím zobrazíte obrázek v plné velikosti).

Pokud ručně přidáte sortExpression pole řetězce dotazu, například SortingWithDefaultPaging.aspx?sortExpression=CategoryName výsledky, budou seřazeny podle zadaného sortExpressionřetězce . Tento sortExpression parametr však není součástí řetězce dotazu při přechodu na jinou stránku dat. Když kliknete na tlačítko Další nebo Poslední stránka, vrátíme se zpátky na Paging.aspx! Kromě toho v současné době neexistuje žádné rozhraní pro řazení. Jediným způsobem, jak může uživatel změnit pořadí řazení stránkovaných dat, je přímá manipulace s řetězcem dotazu.

Vytvoření rozhraní pro řazení

Nejprve musíme aktualizovat metodu RedirectUser tak, aby odeslala uživatele do SortingWithDefaultPaging.aspx (místo ) Paging.aspxa zahrnula sortExpression hodnotu do řetězce dotazu. Měli bychom také přidat pojmenovanou SortExpression vlastnost jen pro čtení na úrovni stránky. Tato vlastnost, podobně jako PageIndex vlastnosti a PageSize vytvořené v předchozím kurzu, vrátí hodnotu sortExpression pole řetězce dotazu, pokud existuje, a v opačném případě výchozí hodnotu (ProductName).

RedirectUser V současné době metoda přijímá pouze jeden vstupní parametr indexu stránky k zobrazení. Může se ale stát, že chceme uživatele přesměrovat na konkrétní stránku dat pomocí jiného výrazu řazení, než je zadaný v řetězci dotazu. Za chvíli vytvoříme pro tuto stránku rozhraní pro řazení, které bude obsahovat řadu webových ovládacích prvků Button pro řazení dat podle zadaného sloupce. Po kliknutí na jedno z těchto tlačítek chceme přesměrovat uživatele, který předává příslušnou hodnotu výrazu řazení. Chcete-li poskytnout tuto funkci, vytvořte dvě verze RedirectUser metody . První by měl přijímat pouze index stránky, který se má zobrazit, zatímco druhý přijímá index stránky a výraz řazení.

private string SortExpression
{
    get
    {
        if (!string.IsNullOrEmpty(Request.QueryString["sortExpression"]))
            return Request.QueryString["sortExpression"];
        else
            return "ProductName";
    }
}
private void RedirectUser(int sendUserToPageIndex)
{
    // Use the SortExpression property to get the sort expression
    // from the querystring
    RedirectUser(sendUserToPageIndex, SortExpression);
}
private void RedirectUser(int sendUserToPageIndex, string sendUserSortingBy)
{
   // Send the user to the requested page with the requested sort expression
   Response.Redirect(string.Format(
      "SortingWithDefaultPaging.aspx?pageIndex={0}&pageSize={1}&sortExpression={2}",
      sendUserToPageIndex, PageSize, sendUserSortingBy));
}

V prvním příkladu v tomto kurzu jsme vytvořili rozhraní pro řazení pomocí dropDownList. V tomto příkladu použijeme tři webové ovládací prvky Button umístěné nad objektem DataList a jeden pro řazení podle ProductName, jeden pro CategoryNamea jeden pro SupplierName. Přidejte tři webové ovládací prvky Button a nastavte jejich ID vlastnosti a Text odpovídajícím způsobem:

<p>
    <asp:Button runat="server" id="SortByProductName"
        Text="Sort by Product Name" />
    <asp:Button runat="server" id="SortByCategoryName"
        Text="Sort by Category" />
    <asp:Button runat="server" id="SortBySupplierName"
        Text="Sort by Supplier" />
</p>

Dále pro každou z nich vytvořte obslužnou Click rutinu události. Obslužné rutiny událostí by měly volat metodu RedirectUser a vrátit uživatele na první stránku pomocí příslušného výrazu řazení.

protected void SortByProductName_Click(object sender, EventArgs e)
{
    // Sort by ProductName
    RedirectUser(0, "ProductName");
}
protected void SortByCategoryName_Click(object sender, EventArgs e)
{
    // Sort by CategoryName
    RedirectUser(0, "CategoryName");
}
protected void SortBySupplierName_Click(object sender, EventArgs e)
{
    // Sort by SupplierName
    RedirectUser(0, "SupplierName");
}

Při první návštěvě stránky se data seřadí abecedně podle názvu produktu (viz obrázek 9). Kliknutím na tlačítko Další přejděte na druhou stránku dat a potom klikněte na tlačítko Seřadit podle kategorie. Tím se vrátíme na první stránku dat seřazenou podle názvu kategorie (viz Obrázek 10). Podobně kliknutím na tlačítko Seřadit podle dodavatele seřadíte data podle dodavatele od první stránky dat. Volba řazení se při procházení dat stránkováním zapamatuje. Obrázek 11 znázorňuje stránku po seřazení podle kategorie a následném postupu na třináctou stránku dat.

Produkty jsou seřazené podle kategorie.

Obrázek 10: Produkty jsou seřazené podle kategorie (kliknutím zobrazíte obrázek v plné velikosti)

Výraz sort se zapamatuje při stránkování dat.

Obrázek 11: Výraz řazení se zapamatuje při stránkování dat (kliknutím zobrazíte obrázek v plné velikosti)

Krok 6: Vlastní stránkování záznamů v opakovači

Příklad DataList prozkoumaný v kroku 5 stránek prostřednictvím svých dat pomocí neefektivní výchozí techniky stránkování. Při stránkování dostatečně velkých objemů dat je nutné použít vlastní stránkování. Zpět v kurzech Efektivní stránkování velkými objemy dat a Řazení vlastních stránkovaných dat jsme prozkoumali rozdíly mezi výchozím a vlastním stránkováním a vytvořili jsme metody v BLL pro využití vlastního stránkování a řazení vlastních stránkovaných dat. Konkrétně v těchto dvou předchozích kurzech jsme do ProductsBLL třídy přidali následující tři metody:

  • GetProductsPaged(startRowIndex, maximumRows) vrátí konkrétní podmnožinu záznamů počínaje počátečním indexem startRowIndex a nepřekračující hodnotu maximumRows.
  • GetProductsPagedAndSorted(sortExpression, startRowIndex, maximumRows) vrátí konkrétní podmnožinu záznamů seřazených podle zadaného vstupního parametru sortExpression .
  • TotalNumberOfProducts() poskytuje celkový počet záznamů v tabulce Products databáze.

Tyto metody lze použít k efektivnímu stránkování a řazení dat pomocí ovládacího prvku DataList nebo Repeater. Pro ilustraci začněme vytvořením ovládacího prvku Repeater s podporou vlastního stránkování; Pak přidáme možnosti řazení.

SortingWithCustomPaging.aspx Otevřete stránku ve PagingSortingDataListRepeater složce a přidejte na stránku repeater s nastavením jeho ID vlastnosti na Products. Z inteligentní značky Repeater vytvořte nový ObjectDataSource s názvem ProductsDataSource. Nakonfigurujte ho tak, aby vybírejte data z ProductsBLL metody třídy s GetProductsPaged .

Konfigurace ObjectDataSource pro použití třídy ProductsBLL s GetProductsPaged Metoda

Obrázek 12: Konfigurace objektu ObjectDataSource pro použití ProductsBLL metody Class s GetProductsPaged (kliknutím zobrazíte obrázek v plné velikosti)

Nastavte rozevírací seznamy na kartách AKTUALIZOVAT, VLOŽIT a ODSTRANIT na (Žádný) a potom klikněte na tlačítko Další. Průvodce konfigurací zdroje dat teď zobrazí výzvu ke zdrojům vstupních GetProductsPaged parametrů metody startRowIndex a maximumRows . Ve skutečnosti jsou tyto vstupní parametry ignorovány. Místo toho budou hodnoty startRowIndex a maximumRows předány prostřednictvím Arguments vlastnosti v obslužné rutině události ObjectDataSource Selecting , stejně jako jsme zadali sortExpression v první ukázce tohoto kurzu. Proto ponechte v průvodci rozevírací seznamy zdroje parametrů nastavené na None .

Zdroje parametrů nechejte nastavené na Žádné.

Obrázek 13: Nechejte zdroje parametrů nastavené na Žádné (kliknutím zobrazíte obrázek v plné velikosti)

Poznámka

Nenastavujte vlastnost ObjectDataSource na EnablePagingtruehodnotu . To způsobí, že ObjectDataSource automaticky zahrne vlastní parametry startRowIndex a maximumRows do existujícího SelectMethod seznamu parametrů s. Vlastnost EnablePaging je užitečná při vazbě vlastních stránkovaných dat na ovládací prvek GridView, DetailsView nebo FormView, protože tyto ovládací prvky očekávají určité chování z ObjectDataSource, které je k dispozici pouze v případě EnablePaging , že vlastnost je true. Vzhledem k tomu, že musíme ručně přidat podporu stránkování pro DataList a Repeater, nechte tuto vlastnost nastavenou na false (výchozí), protože v potřebné funkci se budeme péct přímo v rámci naší ASP.NET stránky.

Nakonec definujte repeatery ItemTemplate tak, aby se zobrazil název produktu, kategorie a dodavatel. Po těchto změnách by deklarativní syntaxe Repeater a ObjectDataSource měla vypadat nějak takto:

<asp:Repeater ID="Products" runat="server" DataSourceID="ProductsDataSource"
    EnableViewState="False">
    <ItemTemplate>
        <h4><asp:Label ID="ProductNameLabel" runat="server"
            Text='<%# Eval("ProductName") %>'></asp:Label></h4>
        Category:
        <asp:Label ID="CategoryNameLabel" runat="server"
            Text='<%# Eval("CategoryName") %>'></asp:Label><br />
        Supplier:
        <asp:Label ID="SupplierNameLabel" runat="server"
            Text='<%# Eval("SupplierName") %>'></asp:Label><br />
        <br />
        <br />
    </ItemTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetProductsPaged" TypeName="ProductsBLL">
    <SelectParameters>
        <asp:Parameter Name="startRowIndex" Type="Int32" />
        <asp:Parameter Name="maximumRows" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

Věnujte chvíli návštěvě stránky v prohlížeči a všimněte si, že se nevrátí žádné záznamy. Je to proto, že jsme ještě zadat startRowIndex a maximumRows hodnoty parametru ; proto se hodnoty 0 předávají pro oba. Pokud chcete zadat tyto hodnoty, vytvořte obslužnou rutinu události pro událost ObjectDataSource Selecting a programově nastavte tyto hodnoty parametrů na pevně zakódované hodnoty 0 a 5:

protected void ProductsDataSource_Selecting
    (object sender, ObjectDataSourceSelectingEventArgs e)
{
    e.InputParameters["startRowIndex"] = 0;
    e.InputParameters["maximumRows"] = 5;
}

Po této změně se na stránce při zobrazení v prohlížeči zobrazí prvních pět produktů.

Zobrazí se prvních pět záznamů.

Obrázek 14: Zobrazí se prvních pět záznamů (kliknutím zobrazíte obrázek v plné velikosti)

Poznámka

Produkty uvedené na obrázku 14 jsou seřazené podle názvu produktu, protože GetProductsPaged uložená procedura, která provádí efektivní vlastní stránkovací dotaz, řadí výsledky podle ProductName.

Aby uživatel mohl stránky procházet, musíme sledovat index počátečního řádku a maximální počet řádků a pamatovat si tyto hodnoty napříč zpětnými operacemi. Ve výchozím příkladu stránkování jsme k zachování těchto hodnot použili pole řetězce dotazů. u této ukázky zachovají tyto informace ve stavu zobrazení stránky. Vytvořte následující dvě vlastnosti:

private int StartRowIndex
{
    get
    {
        object o = ViewState["StartRowIndex"];
        if (o == null)
            return 0;
        else
            return (int)o;
    }
    set
    {
        ViewState["StartRowIndex"] = value;
    }
}
private int MaximumRows
{
    get
    {
        object o = ViewState["MaximumRows"];
        if (o == null)
            return 5;
        else
            return (int)o;
    }
    set
    {
        ViewState["MaximumRows"] = value;
    }
}

Dále aktualizujte kód v obslužné rutině události Výběr tak, aby místo pevně zakódovaných hodnot 0 a 5 používal StartRowIndex vlastnosti a MaximumRows :

e.InputParameters["startRowIndex"] = StartRowIndex;
e.InputParameters["maximumRows"] = MaximumRows;

V tomto okamžiku se na naší stránce zobrazuje jenom prvních pět záznamů. S těmito vlastnostmi však jsme připraveni vytvořit naše stránkovací rozhraní.

Přidání stránkovacího rozhraní

Použijte stejné rozhraní prvního, předchozího, dalšího, posledního stránkování použitého ve výchozím příkladu stránkování, včetně ovládacího prvku Label Web, který zobrazuje, jaká stránka dat se zobrazuje a kolik stránek celkem existuje. Přidejte čtyři ovládací prvky Button Web (Web) a Label (Popisek) pod repeater.

<p>
    <asp:Button runat="server" ID="FirstPage" Text="<< First" />
    <asp:Button runat="server" ID="PrevPage" Text="< Prev" />
    <asp:Button runat="server" ID="NextPage" Text="Next >" />
    <asp:Button runat="server" ID="LastPage" Text="Last >>" />
</p>
<p>
    <asp:Label runat="server" ID="CurrentPageNumber"></asp:Label>
</p>

Dále vytvořte Click obslužné rutiny událostí pro čtyři tlačítka. Po kliknutí na jedno z těchto tlačítek musíme aktualizovat StartRowIndex data a znovu je připojit k opakovači. Kód pro tlačítka První, Předchozí a Další je dostatečně jednoduchý, ale jak pro tlačítko Poslední určíme index počátečního řádku pro poslední stránku dat? Abychom mohli vypočítat tento index a zjistit, jestli mají být povolená tlačítka Další a Poslední, potřebujeme vědět, kolik záznamů se celkem stránkuje. To můžeme zjistit voláním ProductsBLL metody třídy s TotalNumberOfProducts() . Pojďme vytvořit vlastnost TotalRowCount na úrovni stránky jen pro čtení, která vrátí výsledky TotalNumberOfProducts() metody:

private int TotalRowCount
{
    get
    {
        // Return the value from the TotalNumberOfProducts() method
        ProductsBLL productsAPI = new ProductsBLL();
        return productsAPI.TotalNumberOfProducts();
    }
}

Pomocí této vlastnosti teď můžeme určit index počátečního řádku poslední stránky. Konkrétně se jedná o celočíselný výsledek TotalRowCount minus 1 dělený MaximumRowsa vynásobený MaximumRows. Teď můžeme napsat obslužné Click rutiny událostí pro čtyři tlačítka stránkovacího rozhraní:

protected void FirstPage_Click(object sender, EventArgs e)
{
    // Return to StartRowIndex of 0 and rebind data
    StartRowIndex = 0;
    Products.DataBind();
}
protected void PrevPage_Click(object sender, EventArgs e)
{
    // Subtract MaximumRows from StartRowIndex and rebind data
    StartRowIndex -= MaximumRows;
    Products.DataBind();
}
protected void NextPage_Click(object sender, EventArgs e)
{
    // Add MaximumRows to StartRowIndex and rebind data
    StartRowIndex += MaximumRows;
    Products.DataBind();
}
protected void LastPage_Click(object sender, EventArgs e)
{
    // Set StartRowIndex = to last page's starting row index and rebind data
    StartRowIndex = ((TotalRowCount - 1) / MaximumRows) * MaximumRows;
    Products.DataBind();
}

Nakonec musíme zakázat tlačítka První a Předchozí ve stránkovacím rozhraní při prohlížení první stránky dat a tlačítka Další a Poslední při prohlížení poslední stránky. Chcete-li toho dosáhnout, přidejte následující kód do obslužné rutiny události ObjectDataSource s Selecting :

// Disable the paging interface buttons, if needed
FirstPage.Enabled = StartRowIndex != 0;
PrevPage.Enabled = StartRowIndex != 0;
int LastPageStartRowIndex = ((TotalRowCount - 1) / MaximumRows) * MaximumRows;
NextPage.Enabled = StartRowIndex < LastPageStartRowIndex;
LastPage.Enabled = StartRowIndex < LastPageStartRowIndex;

Po přidání těchto Click obslužných rutin událostí a kódu pro povolení nebo zakázání prvků stránkovacího rozhraní na základě aktuálního indexu počátečního řádku otestujte stránku v prohlížeči. Jak znázorňuje obrázek 15, při první návštěvě stránky budou tlačítka První a Předchozí zakázaná. Kliknutím na Další se zobrazí druhá stránka dat, zatímco kliknutím na Poslední se zobrazí poslední stránka (viz Obrázky 16 a 17). Při prohlížení poslední stránky dat jsou zakázána tlačítka Další i Poslední.

Tlačítka Předchozí a Poslední jsou při zobrazení první stránky produktů zakázaná.

Obrázek 15: Tlačítka Předchozí a Poslední jsou při prohlížení první stránky produktů zakázaná (kliknutím zobrazíte obrázek v plné velikosti)

Zobrazí se druhá stránka produktů.

Obrázek 16: Zobrazí se druhá stránka produktů (kliknutím zobrazíte obrázek v plné velikosti)

Kliknutím na poslední zobrazíte poslední stránku dat.

Obrázek 17: Kliknutí na poslední zobrazí konečnou stránku dat (kliknutím zobrazíte obrázek v plné velikosti)

Krok 7: Zahrnutí podpory řazení pomocí vlastního stránkovacího opakovače

Teď, když jsme implementovali vlastní stránkování, jsme připraveni zahrnout podporu řazení. Metoda ProductsBLL třídy s GetProductsPagedAndSorted má stejné vstupní parametry startRowIndex a maximumRows jako GetProductsPaged, ale povoluje další vstupní parametr sortExpression . Abychom mohli použít metodu GetProductsPagedAndSorted z SortingWithCustomPaging.aspxnástroje , musíme provést následující kroky:

  1. Změňte vlastnost GetProductsPaged ObjectDataSource z SelectMethod na GetProductsPagedAndSorted.
  2. Přidejte objekt sortExpressionParameter do kolekce ObjectDataSource s SelectParameters .
  3. Vytvořte soukromou vlastnost na úrovni SortExpression stránky, která zachová svou hodnotu napříč zpětnými operacemi ve stavu zobrazení stránky.
  4. Aktualizujte obslužnou rutinu události ObjectDataSource s Selecting a přiřaďte parametru ObjectDataSource s sortExpression hodnotu vlastnosti na úrovni SortExpression stránky.
  5. Vytvořte rozhraní pro řazení.

Začněte aktualizací vlastnosti ObjectDataSource s SelectMethod a přidáním sortExpressionParameter. Ujistěte se, že vlastnost sortExpressionParameter s Type je nastavená na Stringhodnotu . Po dokončení těchto dvou úloh by deklarativní značka ObjectDataSource měla vypadat takto:

<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
    SelectMethod="GetProductsPagedAndSorted"
    OnSelecting="ProductsDataSource_Selecting">
    <SelectParameters>
        <asp:Parameter Name="sortExpression" Type="String" />
        <asp:Parameter Name="startRowIndex" Type="Int32" />
        <asp:Parameter Name="maximumRows" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

Dále potřebujeme vlastnost na úrovni SortExpression stránky, jejíž hodnota je serializována pro zobrazení stavu. Pokud není nastavená žádná hodnota výrazu řazení, použijte jako výchozí hodnotu ProductName:

private string SortExpression
{
    get
    {
        object o = ViewState["SortExpression"];
        if (o == null)
            return "ProductName";
        else
            return o.ToString();
    }
    set
    {
        ViewState["SortExpression"] = value;
    }
}

Než ObjectDataSource vyvolá metodu GetProductsPagedAndSorted , musíme nastavit sortExpressionParameter na hodnotu SortExpression vlastnosti. Do obslužné rutiny Selecting události přidejte následující řádek kódu:

e.InputParameters["sortExpression"] = SortExpression;

Zbývá jen implementovat rozhraní pro řazení. Stejně jako v posledním příkladu nechte rozhraní pro řazení implementovat pomocí tří webových ovládacích prvků Button, které uživateli umožňují řadit výsledky podle názvu produktu, kategorie nebo dodavatele.

<asp:Button runat="server" id="SortByProductName"
    Text="Sort by Product Name" />
<asp:Button runat="server" id="SortByCategoryName"
    Text="Sort by Category" />
<asp:Button runat="server" id="SortBySupplierName"
    Text="Sort by Supplier" />

Vytvořte Click obslužné rutiny událostí pro tyto tři ovládací prvky Tlačítko. V obslužné rutině události resetujte StartRowIndex hodnotu na hodnotu 0, nastavte SortExpression hodnotu na příslušnou hodnotu a znovu nastavte vaz dat na repeater:

protected void SortByProductName_Click(object sender, EventArgs e)
{
    StartRowIndex = 0;
    SortExpression = "ProductName";
    Products.DataBind();
}
protected void SortByCategoryName_Click(object sender, EventArgs e)
{
    StartRowIndex = 0;
    SortExpression = "CategoryName";
    Products.DataBind();
}
protected void SortBySupplierName_Click(object sender, EventArgs e)
{
    StartRowIndex = 0;
    SortExpression = "CompanyName";
    Products.DataBind();
}

To je vše, co k tomu patří! I když existovalo několik kroků, jak implementovat vlastní stránkování a řazení, tyto kroky byly velmi podobné těm, které byly potřeba pro výchozí stránkování. Obrázek 18 znázorňuje produkty při zobrazení poslední stránky dat seřazených podle kategorií.

Zobrazí se poslední stránka dat seřazená podle kategorie.

Obrázek 18: Zobrazí se poslední stránka dat seřazená podle kategorie (kliknutím zobrazíte obrázek v plné velikosti).

Poznámka

V předchozích příkladech se při řazení podle dodavatele SupplierName použilo jako výraz řazení. Pro implementaci vlastního stránkování však musíme použít CompanyName. Je to proto, že uložená procedura zodpovědná za implementaci vlastního stránkování GetProductsPagedAndSorted předává výraz řazení do klíčového ROW_NUMBER() slova , Klíčové ROW_NUMBER() slovo vyžaduje skutečný název sloupce místo aliasu. Proto musíme pro výraz řazení místo aliasu použitého v SELECT dotazu (SupplierName) použít CompanyName (název sloupce v Suppliers tabulce).

Souhrn

DataList ani Repeater nenabízí integrovanou podporu řazení, ale s trochou kódu a vlastním rozhraním pro řazení je možné tyto funkce přidat. Při implementaci řazení, ale ne stránkování, lze výraz řazení zadat prostřednictvím objektu DataSourceSelectArguments předaného do ObjectDataSource s Select metody. Tuto DataSourceSelectArguments vlastnost objektu s SortExpression lze přiřadit v obslužné rutině události ObjectDataSource.Selecting

Pokud chcete přidat možnosti řazení do datalistu nebo repeateru, který už stránkování podporuje, nejjednodušším způsobem je přizpůsobit vrstvu obchodní logiky tak, aby zahrnovala metodu, která přijímá výraz řazení. Tyto informace lze pak předat prostřednictvím parametru v ObjectDataSource s SelectParameters.

Tento kurz dokončí zkoumání stránkování a řazení pomocí ovládacích prvků DataList a Repeater. V dalším a posledním kurzu se podíváme, jak přidat webové ovládací prvky Button do šablon DataList a Repeater s, aby bylo možné poskytnout některé vlastní funkce iniciované uživatelem na základě jednotlivých položek.

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