zoner.cz | czechia.com | regzone.cz | zoner-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.


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

Tematicky související články

Dejte vědět i ostatním o článku

  • Facebook
  • Linkuj.cz!
  • Jaggni to!
  • MediaBlog.cz
  • TOPodkazy.cz
  • Bookmarky.cz
  • Top Články.cz
  • Blogus.cz
  • del.icio.us
  • Technorati
  • Digg
  • LinkedIn
  • Google Bookmarks

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é. Minimální délka vašeho komentáře je 15 znaků.

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.