Stránkovací prvek Pagination pro formuláře ASP.NET - použití
10. 09. 2007 | Pavel Růžička | ASP.NET | Komentáře: 0
V tomto článku navazuji na předchozí text, který byl věnován vnitřní architektuře prvku. Probereme detailně veřejné členy a připravíme ukázku použití pro stránkování, kdy známe celkový počet záznamů, ale také pro případ, kdy celkový počet neznáme nebo je jeho zjištění komplikované a náročné.
Jak jsme si popsali v předchozím článku, prvek Pagination zajišťuje inteligentní vykreslení daného počtu čísel stránek a automaticky doplní odkaz na "další sadu stránek". Prvky, které nemají v dané situaci smysl, jsou zakázané (například přechod na předchozí stránku v situaci, kdy jsme na první stránce). Je možné volit z režimu zobrazení tlačítek vpřed a zpět nebo číselných radibuttonů nebo zobrazit obojí (viz ukázky vzhledu).
K dispozici je vám kompletní zdrojový kód tohoto prvku ke stažení a otestování.
Veřejní členové - implementace
Nejdříve si ukážeme jejich implementaci - v podstatě na ní není nic převratného, proto jsem v kódu ponechal také interní anglické komentáře a níže jsem připravil pouze přehledný seznam členů s českým komentářem.
/// <summary>
/// Go button text
/// </summary>
public String GoToPageText
{
get
{
return btnGo.Text;
}
set
{
btnGo.Text = value;
}
}
/// <summary>
/// Go button tooltip
/// </summary>
public String GoToPageToolTip
{
get
{
return btnGo.ToolTip;
}
set
{
btnGo.ToolTip = value;
}
}
/// <summary>
/// Numeric pages tooltip
/// </summary>
public String NumericPagesToolTip
{
get
{
return rblNumeric.ToolTip;
}
set
{
rblNumeric.ToolTip = value;
}
}
/// <summary>
/// Next page button text
/// </summary>
public String NextPageText
{
get
{
return btnNext.Text;
}
set
{
btnNext.Text = value;
}
}
/// <summary>
/// Next page button tooltip
/// </summary>
public String NextPageToolTip
{
get
{
return btnNext.ToolTip;
}
set
{
btnNext.ToolTip = value;
}
}
/// <summary>
/// Previous page button text
/// </summary>
public String PrevPageText
{
get
{
return btnPrev.Text;
}
set
{
btnPrev.Text = value;
}
}
/// <summary>
/// Previous page button tooltip
/// </summary>
public String PrevPageToolTip
{
get
{
return btnPrev.ToolTip;
}
set
{
btnPrev.ToolTip = value;
}
}
/// <summary>
/// Button CSS class
/// </summary>
public String ButtonCssClass
{
get
{
return lblNextPrev.CssClass;
}
set
{
lblNextPrev.CssClass = lblGo.CssClass = value;
}
}
/// <summary>
/// RadioButton CSS class
/// </summary>
public String RadioButtonCssClass
{
get
{
return rblNumeric.CssClass;
}
set
{
rblNumeric.CssClass = value;
}
}
/// <summary>
/// Gets or sets the virtual number of items in the Pagination control.
/// </summary>
public Int32 VirtualItemCount
{
get
{
object o = this.ViewState["VirtualItemCount"];
if (o != null)
return (Int32) o;
else
return _virtualItemCount;
}
set
{
this.ViewState["VirtualItemCount"] = value;
virtualItemCount = value;
}
}
/// <summary>
/// Gets or sets the index of the currently displayed page.
/// </summary>
public Int32 SelectedPageIndex
{
get
{
object o = this.ViewState["SelectedPageIndex"];
if (o != null)
return (Int32) o;
else
return _selectedPageIndex;
}
set
{
this.ViewState["SelectedPageIndex"] = value;
selectedPageIndex = value;
}
}
/// <summary>
/// Gets total number of pages to pagination.
/// </summary>
public Int32 PageCount
{
get
{
_calculatePageCount();
return _pageCount;
}
}
/// <summary>
/// Gets or sets the number of items to display on a single page of the paginated control.
/// </summary>
public Int32 PageSize
{
get
{
object o = this.ViewState["PageSize"];
if (o != null)
return (Int32) o;
else
return _pageSize;
}
set
{
this.ViewState["PageSize"] = value;
_pageSize = value;
}
}
/// <summary>
/// Gets or sets the number of numeric buttons to display concurrently
/// </summary>
public Int32 PageButtonCount
{
get
{
object o = this.ViewState["PageButtonCount"];
if (o != null)
return (Int32) o;
else
return _pageButtonCount;
}
set
{
this.ViewState["PageButtonCount"] = value;
_pageButtonCount = value;
}
}
/// <summary>
/// Gets or sets the direction that the radio buttons within the group are displayed.
/// </summary>
public PaginationNumericRepeatDirection NumericRepeatDirection
{
get { return _numericRepeatDirection; }
set { _numericRepeatDirection = value; }
}
/// <summary>
/// Gets or sets a value that specifies whether the pager element displays buttons that link to the next and previous page, or numeric radio buttons.
/// </summary>
public PaginationMode Mode
{
get { return _mode; }
set { _mode = value; }
}
/// <summary>
/// Gets or sets a value indicating whether validation is performed when the control is clicked.
/// </summary>
public Boolean CausesValidation
{
get
{
return btnPrev.CausesValidation;
}
set
{
btnPrev.CausesValidation = btnNext.CausesValidation = btnGo.CausesValidation = rblNumeric.CausesValidation = value;
}
}
U některých vlastností vidíme, jak je jejich hodnota udržována prostřednictvím ViewState, což je samozřejmě důležité - aby vlastnosti stránkovacího prvku přežily PostBack.
Veřejní členové - přehledný popis
Vlastnosti
public String GoToPageText- text tlačítka pro přechod na zvolenou stránku, tlačítko se zobrazuje pouze pokud klient nepodporuje JavaScriptpublic String GoToPageToolTip- tooltip tlačítka pro přechod na zvolenou stránku, tlačítko se zobrazuje pouze pokud klient nepodporuje JavaScriptpublic String NumericPagesToolTip- tooltip radiobuttonů pro přechod na zvolenou stránkupublic String NextPageText- text tlačítka pro přechod na následující stránkupublic String NextPageToolTip- tooltip tlačítka pro přechod na následující stránkupublic String PrevPageText- text tlačítka pro přechod na předchozí stránkupublic String PrevPageToolTip- text tlačítka pro přechod na následující stránkupublic String ButtonCssClass- třída CSS pro tlačítkapublic String RadioButtonCssClass- třída CSS pro radiobuttonypublic Int32 VirtualItemCount- vrací nebo nastaví virtuální (celkový) počet položek, které jsou stránkovány - vlastnost má týž význam, jako u prvků DataGrid nebo GridViewpublic Int32 SelectedPageIndex- vrací nebo nastaví index právě zvolené stránkypublic Int32 PageCount- pouze vrací celkový počet stránek ke stránkovánípublic Int32 PageSize- vrací nebo nastaví počet položek v jedné stránce - vlastnost má týž význam, jako u prvků DataGrid nebo GridViewpublic Int32 PageButtonCount- vrací nebo nastaví maximální počet položek číselných buttonů (čísel) stránek, na konci nebo začátku seznamu je generován odkaz pro přechod na "další sadu" stránek, pokud nějaká předchází či následuje - vlastnost má týž význam, jako u prvků DataGrid nebo GridViewpublic PaginationNumericRepeatDirection NumericRepeatDirection- styl zobrazení čísel stránek - radiobuttonůpublic PaginationMode Mode- režim zobrazení stránkovacích prvkůpublic Boolean CausesValidation- nastavuje, zda použití prvku vyvolává validaci stránky
Události
public event EventHandler SelectedPageIndexChanged- je vyvolána v okamžiku, kdy je změněn index zvolené stránky, hodí se tedy pro získání dat dané stránky z datového zdroje a navázání na zobrazovací prvek
Enumerace
public enum PaginationMode- režim zobrazení ovládacích prvků- AllControls (čísla stránek i tlačítka vpřed a zpět)
- NextPrev (pouze tlačítka vpřed a zpět)
- Numeric (pouze čísla stránek)
public enum PaginationNumericRepeatDirection- způsob zobrazení čísel stránek- Horizontal (vodorovně)
- Vertical (svisle)
Příklad použití pro SqlDataReader k naplnění Repeateru s využitím stránkovací procedury
Tento prvek se výborně hodí pro použití ve spojení s univerzální stránkovací procedurou.
private void Page_Load(object sender, System.EventArgs e)
{
// nastavit lokalizované texty a tooltipy stránkovacího prvku
pgnSearch.GoToPageText = LocalizationManager.GetString("PaginationGoToPageText");
pgnSearch.GoToPageToolTip = LocalizationManager.GetString("PaginationGoToPageToolTip");
pgnSearch.NumericPagesToolTip = LocalizationManager.GetString("PaginationNumericPagesToolTip");
pgnSearch.NextPageText = LocalizationManager.GetString("PaginationNextPageText");
pgnSearch.NextPageToolTip = LocalizationManager.GetString("PaginationNextPageToolTip");
pgnSearch.PrevPageText = LocalizationManager.GetString("PaginationPrevPageText");
pgnSearch.PrevPageToolTip = LocalizationManager.GetString("PaginationPrevPageToolTip");
..
if (!Page.IsPostBack)
Bind_Page(sender, e); }
private void Bind_Page(Object sender, EventArgs e)
{
using (SqlConnection connection = new SqlConnection(PublicDBReaderString))
{
using (SqlCommand myCmd = new SqlCommand("[dbo].[PaginateTable]",connection))
{
myCmd.CommandType = CommandType.StoredProcedure;
myCmd.Parameters.Add("@PageSize", SqlDbType.Int).Value = pgnSearch.PageSize;
myCmd.Parameters.Add("@CurrentPageIndex", SqlDbType.Int).Value = pgnSearch.SelectedPageIndex;
myCmd.Parameters.Add("@TableName", SqlDbType.VarChar,64).Value = "[dbo].[Events]";
myCmd.Parameters.Add("@KeyField", SqlDbType.VarChar,32).Value = "[EventDate]";
myCmd.Parameters.Add("@RowFilter", SqlDbType.VarChar,3128).Value = "DATEDIFF(dd,[EventDate],GETDATE()) <= 0";
try
{
connection.Open();
using (SqlDataReader myReader = myCmd.ExecuteReader(CommandBehavior.CloseConnection))
{
if (myReader.Read())
pgnSearch.VirtualItemCount = myReader.GetInt32(0);
else
pgnSearch.VirtualItemCount = 0;
if (pgnSearch.PageCount > 1)
pgnSearch.Visible = true;
else
pgnSearch.Visible = false;
myReader.NextResult();
rptSearch.DataSource = myReader;
rptSearch.DataBind();
}
}
catch
{
lblError.Visible = true;
}
}
}
}
private void InitializeComponent()
{ // zaregistrovat obsluhy událostí
this.pgnSearch.SelectedPageIndexChanged += new System.EventHandler(this.Bind_Page);
this.Load += new System.EventHandler(this.Page_Load);
}
V této ukázce principu řešení vidíme naplnění Repeateru zdrojem dat a také nastavení hodnot stránkovacího prvku - tak, aby byl v souladu počet skutečně vrácených záznamů ze zdroje pro danou stránku a vlastnosti stránkovacího prvku. Vidíme také zaregistrovanou obsluhu události při změně indexu stránky - voláme jedinou metodu, načtení správných řádků pro danou stránku je v ní zajištěno právě využitím vlastností stránkovacího prvku, který údaje o zvolené stránce i o počtu řádků pro stránku sám udržuje.
Příklad použití v designu stránky
<div class="pagingElement">
<Pc:Pagination Id="pgnSearch" Mode="AllControls" Visible="False" CausesValidation="False" ButtonCssClass="pageButton" RadioButtonCssClass="pageRadio" PageButtonCount="5" PageSize="10" RunAt="server" />
</div>
V ukázce vidíme nastavení režimu na číslované stránky i tlačítka vpřed a zpět, je nastavena třída stylu pro tlačítka i radiobuttony, počet čísel stránek je nastaven na maximálně 5 a počet řádků na stránce na 10.
Stránkování, kdy neznáme celkový počet záznamů
Takové stránkování je zdánlivě neřešitelné, ovšem jedna možnost zde je. Musíme splnit dvě podmínky - jednak musíme vypnout volbu číslovaných stránek a jednak nám zdroj dat musí poskytnout údaj o tom, zda za právě vrácenými záznamy je možné očekávat ještě alespoň jeden následující (je možný přechod na další stránku). Když toto splníme, řešení může vypadat takto:
if (Results.HasNext)
pgnSearch.VirtualItemCount = 2000;
else
{
if (Results.Length == pgnSearch.PageSize)
pgnSearch.VirtualItemCount = pgnSearch.SelectedPageIndex*pgnSearch.PageSize;
else
pgnSearch.VirtualItemCount = (pgnSearch.SelectedPageIndex*pgnSearch.PageSize)-pgnSearch.PageSize + Results.Length;
}
Vlastnost Results.HasNext ukazuje, zda jsou k dispozici ještě nějaké další záznamy - pokud ano, jednoduše nastavíme celkový počet stránek na nějakou přiměřeně vysokou hodnotu. Pokud ne, pak vyhodnotíme, jestli je aktuální stránka zaplněná až do konce, a podle toho potom nastavíme celkový počet záznamů ve vlastnosti VirtualItemCount tak, aby odpovídal skutečnému počtu zobrazitelných záznamů - prvek potom sám rozhodne, zda povolit či zakázat tlačítko pro přechod na další stránku.
Použití v designu bez celkového množství záznamů
<div class="pagingElement">
<Pc:Pagination Id="pgnSearch" Mode="NextPrev" Visible="False" CausesValidation="False" ButtonCssClass="pageButton" PageSize="10" RunAt="server" />
</div>
V ukázce vidíme nastavení režimu pouze na tlačítka vpřed a zpět, je nastavena třída stylu pro tlačítka a počet řádků na stránce na 10.
Zbývá dodat, že chystané Visual Studio "Orcas" přichází s novým stránkovacím prvkem DataPager - ten je ovšem závislý na klientském skriptování a tak v případech, kde tuto závislost nechceme, bude mít dále své místo i tento prvek.
Další aktuální články na interval.cz
- Nedostatek paměti pro WordPress 3.0? Co s tím?
- Jaký bude (skutečný) výkon IE9 v prostředí internetu?
- Tipy pro tvorbu lepších vícejazyčných stránek
- Jak připravovat grafický návrh pro kodera?
- Novinky v prohlížečích: Firefox 4.0 beta 4
Tematicky související články
- Stránkovací prvek Pagination pro formuláře ASP.NET - konstrukce
- Stránkovací prvek LinkPagination pro ASP.NET
- Serverový ovládací prvek se šablonou v ASP.NET
- ViewState v ASP.NET aplikacích - implementace a použití
- Jak na mravné formuláře s použitelnou klávesou Enter v ASP.NET
Dejte vědět i ostatním o článku
Diskuse (počet komentářů: 0)
Buďte prvním návštěvníkem, který přidá nový komentář.













