2010-03-25 20 views
1

我想用gridview做高效的分頁而不使用數據源控件。通過高效,我的意思是我只檢索我打算展示的記錄。沒有數據源控制的高效的Gridview分頁的問題

我想使用PagerTemplate來建立我的尋呼機功能。

簡而言之,問題是如果我僅綁定我打算在當前頁面上顯示的記錄,那麼gridview將不會呈現其頁面模板,因此我不會看到分頁控件。

這就好像我必須綁定更多的記錄比我打算在給定的頁面上顯示,這是我不想做的事情。

回答

7

您需要創建一個從GridView繼承的自定義GridView控件。沒有DataSourceControl,gridview並不知道可能綁定到控件的記錄總數。如果綁定100條記錄中的10條並將PageSize屬性設置爲10,那麼gridview只知道有10條記錄小於或等於PageSize,並且尋呼機控件不會顯示。爲了讓你的gridview顯示尋呼機,它必須知道可能被檢索的記錄總數。通過繼承gridview並重寫InitializePager方法,我們可以攔截pagedDataSource並修改AllowCustomPaging和VirtualCount方法。

這是我創建

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Web.UI.WebControls; 
using System.ComponentModel; 

namespace cly.Web.CustomControls 
{ 
    public class clyGridView : GridView 
    { 
     private const string _virtualCountItem = "bg_vitemCount"; 
     private const string _sortColumn = "bg_sortColumn"; 
     private const string _sortDirection = "bg_sortDirection"; 
     private const string _currentPageIndex = "bg_pageIndex"; 

     public clyGridView() 
      : base() 
     { 
     } 

     #region Custom Properties 
     [Browsable(true), Category("NewDynamic")] 
     [Description("Set the virtual item count for this grid")] 
     public int VirtualItemCount 
     { 
      get 
      { 
       if (ViewState[_virtualCountItem] == null) 
        ViewState[_virtualCountItem] = -1; 
       return Convert.ToInt32(ViewState[_virtualCountItem]); 
      } 
      set 
      { 
       ViewState[_virtualCountItem] = value; 
      } 
     }   

     public string GridViewSortColumn 
     { 
      get 
      { 
       if (ViewState[_sortColumn] == null) 
        ViewState[_sortColumn] = string.Empty; 
       return ViewState[_sortColumn].ToString(); 
      } 
      set 
      { 
       if (ViewState[_sortColumn] == null || !ViewState[_sortColumn].Equals(value)) 
        GridViewSortDirection = SortDirection.Ascending; 
       ViewState[_sortColumn] = value; 
      } 
     } 

     public SortDirection GridViewSortDirection 
     { 
      get 
      { 
       if (ViewState[_sortDirection] == null) 
        ViewState[_sortDirection] = SortDirection.Ascending; 
       return (SortDirection)ViewState[_sortDirection]; 
      } 
      set 
      { 
       ViewState[_sortDirection] = value; 
      } 
     } 

     private int CurrentPageIndex 
     { 
      get 
      { 
       if (ViewState[_currentPageIndex] == null) 
        ViewState[_currentPageIndex] = 0; 
       return Convert.ToInt32(ViewState[_currentPageIndex]); 
      } 
      set 
      { 
       ViewState[_currentPageIndex] = value; 
      } 
     } 

     private bool CustomPaging 
     { 
      get { return (VirtualItemCount != -1); } 
     } 
     #endregion 

     #region Overriding the parent methods 
     public override object DataSource 
     { 
      get 
      { 
       return base.DataSource; 
      } 
      set 
      { 
       base.DataSource = value; 
       // store the page index so we don't lose it in the databind event 
       CurrentPageIndex = PageIndex; 
      } 
     } 

     protected override void OnSorting(GridViewSortEventArgs e) 
     {    
      //Store the direction to find out if next sort should be asc or desc 
      SortDirection direction = SortDirection.Ascending; 
      if (ViewState[_sortColumn] != null && (SortDirection)ViewState[_sortDirection] == SortDirection.Ascending) 
      { 
       direction = SortDirection.Descending; 
      } 
      GridViewSortDirection = direction; 
      GridViewSortColumn = e.SortExpression; 
      base.OnSorting(e); 
     } 

     protected override void InitializePager(GridViewRow row, int columnSpan, PagedDataSource pagedDataSource) 
     { 
      // This method is called to initialise the pager on the grid. We intercepted this and override 
      // the values of pagedDataSource to achieve the custom paging using the default pager supplied 
      if (CustomPaging) 
      { 
       pagedDataSource.VirtualCount = VirtualItemCount; 
       pagedDataSource.CurrentPageIndex = CurrentPageIndex; 
      } 
      base.InitializePager(row, columnSpan, pagedDataSource); 
     } 

     protected override object SaveViewState() 
     { 
      //object[] state = new object[3]; 
      //state[0] = base.SaveViewState(); 
      //state[1] = this.dirtyRows; 
      //state[2] = this.newRows; 
      //return state; 

      return base.SaveViewState(); 
     } 

     protected override void LoadViewState(object savedState) 
     { 

      //object[] state = null; 

      //if (savedState != null) 
      //{ 
      // state = (object[])savedState; 
      // base.LoadViewState(state[0]); 
      // this.dirtyRows = (List<int>)state[1]; 
      // this.newRows = (List<int>)state[2]; 
      //} 

      base.LoadViewState(savedState); 
     } 
     #endregion 

     public override string[] DataKeyNames 
     { 
      get 
      { 
       return base.DataKeyNames; 
      } 
      set 
      { 
       base.DataKeyNames = value; 
      } 
     } 

     public override DataKeyArray DataKeys 
     { 
      get 
      { 
       return base.DataKeys; 
      } 
     } 

     public override DataKey SelectedDataKey 
     { 
      get 
      { 
       return base.SelectedDataKey; 
      } 
     } 
    } 
} 

然後,當你要綁定的數據之一:

gv.DataSource = yourListOrWhatever 
gv.VirtualItemCount = numOfTotalRecords; 
gv.DataBind(); 
+0

真的嗎?這是解決這類問題的方法嗎?我知道你不是clyc的錯。我無法想象這是做到這一點的最佳方式。我想我會在gridview下面粘貼一些控件會更好。 – 2010-03-25 20:20:27

+0

gridview不顯示分頁控件的原因是因爲它只知道綁定到控件的記錄數,而不知道潛在記錄的總數。 如果你不想創建一個自定義的gridview,另一種方法是在gridview的底部創建一個單獨的控件,該控件處理獲取你可能返回的項目總數,並計算用戶可以返回的頁數經過。 – clyc 2010-03-25 20:29:56

+0

謝謝。我只是希望有一個技巧或我失蹤的東西。如果gridview上有一個公共可寫屬性用於設置總記錄數,它似乎會變得非常簡單。 – 2010-03-25 20:45:30