Reklama

zonerbooks.cz | zoner.cz | czechia.com | regzone.cz | inshop.cz | inmail.cz | zonerpress.cz | zonerantivirus.com | zonerama.cz

interval.cz

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 JavaScript
  • public String GoToPageToolTip - tooltip tlačítka pro přechod na zvolenou stránku, tlačítko se zobrazuje pouze pokud klient nepodporuje JavaScript
  • public String NumericPagesToolTip - tooltip radiobuttonů pro přechod na zvolenou stránku
  • public String NextPageText - text tlačítka pro přechod na následující stránku
  • public String NextPageToolTip - tooltip tlačítka pro přechod na následující stránku
  • public String PrevPageText - text tlačítka pro přechod na předchozí stránku
  • public String PrevPageToolTip - text tlačítka pro přechod na následující stránku
  • public String ButtonCssClass - třída CSS pro tlačítka
  • public String RadioButtonCssClass - třída CSS pro radiobuttony
  • public 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 GridView
  • public Int32 SelectedPageIndex - vrací nebo nastaví index právě zvolené stránky
  • public 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 GridView
  • public 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 GridView
  • public 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.


Reklama


Další aktuální články na interval.cz

Tematicky související články

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ář.

Přidat nový komentář

Jméno a e-mail jsou nepovinné. Příspěvky obsahující odkaz jsou moderovány.

Zoner AntiVirus Free pro Android
zabezpečte si svůj smartphone, zdarma
Profesionální eshop Zoner inShop od 990 Kč.
Reklama
Reklama

Syndikace

hledáme nové autory | redakce interval.cz | reklama na interval.cz

© ZONER software, a.s., všechna práva vyhrazena, interval.cz dodržuje právní předpisy o ochraně osobních údajů. Powered by WordPress.