2013-01-02 118 views
1

ASP.NET [Horizontal scroll fro GridView] 水平滾動展示瞭如何水平滾動條添加到我的網的ASP.NET沒有尋呼機

的問題是,它也是滾動周圍自動生成的尋呼機。

我可以做外部傳呼機,但肯定會有更好的解決方案嗎?

現在的問題是:是否有一種簡單的方法可以讓我的GridView在水平滾動而不會使頁面滾動。

+0

通過Id或類名查找尋呼機,並使用css隱藏其溢出屬性。 – Dev

+0

它很困難,因爲GridView呈現在表格上,所以它們一起移動,並且不能在div上放置一些行。你可以做到這一點,以提取尋呼機行,並將其放置在表外的div中,在滾動的外側。爲此,您需要使用jQuery來避免大量額外的代碼。 – Aristos

+0

這些都是一些有趣的想法,但沒有js/jq/css的實際知識,我還挺卡在這裏。 – Nahum

回答

0

erich007給了一個非常有趣的答案,這可能是路要走,但我沒有;沒有時間來測試它。

以下方法爲我工作:

報價:

http://blogs.visoftinc.com/2008/03/19/extending-the-gridview-to-work-with-the-new-datapager-control/

擴展GridView控件將工作與新DataPager控件

通過戴夫·馬里尼|發佈日期:2008年3月19日 Technorati標籤:ASP.NET,C#

最近,我閱讀了Scott Mitchell關於.NET Framework 3.5版中包含的新ListView和DataPager控件的文章。這讓我很好奇如何適應GridView等其他衆所周知的數據綁定控件,以便它們可以與DataPager控件一起使用。在閱讀了一些輕量級的內容並且對GridView控件的內容進行了深入的反思之後,我制定了一個遊戲計劃並準備好了。擴展數據綁定控件以允許與DataPager控件進行通信並不太困難,但它確實假定您已理解數據如何綁定到控件。但是爲什麼在GridView內置自己的分頁控件時這麼做呢?那麼,一方面,能夠將尋呼機與電網分離,可以讓我們做一些非常酷的事情。我可以想到的一件事是在左側欄中使用GridView,並在主窗口中使用分頁控件。另外,我們可以有兩個傳呼機的網格。無論我們使用哪一頁來瀏覽我們的數據,每個人都始終跟蹤當前頁面。最後,與單獨的GridView的模板控件相比,尋呼機的模板控件非常強大。

讓我們從數據綁定控件如何與DataPager進行通信開始。 DataPager控件可以連接到任何實現System.Web.Extensions程序集中的IPageableItemContainer接口的控件。這裏的接口是什麼樣子.net反射的禮貌快速射擊:

public interface IPageableItemContainer 
{ 
    //Events 
    event EventHandler<PageEventArgs> TotalRowCountAvailable; 
    // Methods 
    void SetPageProperties(int startRowIndex, int maximumRows, bool databind); 
    // Properties 
    int MaximumRows { get; } 
    int StartRowIndex { get; } 
} 

接口的MaximumRows和StartRowIndex性質只是在那裏爲您的數據綁定控件來確定數據窗口中顯示的方式。這有效地定義了您認爲是數據「頁面」的基礎。 SetPageProperties方法在與DataPager的交互中非常重要,因爲這是控件中DataPager每次單擊任何DataPagerField控件(例如Next或Previous Button)時都會調用的方法。最後,該接口定義了一個名爲TotalRowCountAvailable的事件。此事件告訴DataPager有多少記錄在綁定到您的控件的數據中。這顯然很重要,因爲DataPager使用總行數來確定如何顯示手動頁面按鈕,或者是否禁用下一個或上一個按鈕,以便您不會訪問不存在的頁面索引。

因此,讓我們開始使用DataPager的鉤子擴展GridView。根據GridView思考IPageableItemContainer接口,我們認識到MaximumRows等同於現有的PageSize屬性,並且可以從現有的PageSize和PageIndex屬性計算出StartRowIndex。我們還通過聲明並創建相應的事件調用程序來準備該事件。由於我希望我的新Paging功能成爲此網格的默認功能,因此我強制尋呼機在每次頁面加載時都隱藏自己。如果你願意,你可以添加一個切換到這個行爲。最後,我們列出SetPageProperties方法,但我們暫時將它留空,因爲我們很快會重新訪問它。到目前爲止,我們的新的GridView看起來是這樣的:

public class PageableGridView : GridView, IPageableItemContainer 
{ 
    public PageableGridView() : base() 
    { 
      PagerSettings.Visible = false; 
    } 
    public event EventHandler<PageEventArgs> TotalRowCountAvailable; 
    public int MaximumRows 
    { 
      get{ return this.PageSize; } 
    } 
    public int StartRowIndex 
    { 
      get{ return (this.PageSize * this.PageIndex); } 
    } 
    protected virtual void OnTotalRowCountAvailable(PageEventArgs e) 
    { 
      if (TotalRowCountAvailable != null) 
       TotalRowCountAvailable(this, e); 
    } 
    protected virtual void SetPageProperties(int startRowIndex, int maximumRows, bool dataBind) { } 
} 

好消息是,我們是不是還有一半以上。現在是事情變得更加複雜的地方。我們仍然需要一種方法來根據DataPager說我們需要在用戶單擊其中一個按鈕時顯示的內容來設置頁面大小和起始行值。這是SetPageProperties方法的作用。這是一個基本的實現,能夠完成任務:

保護的虛擬無效SetPageProperties(INT startRowIndex,INT maximumRows,布爾數據綁定) { 如果(數據綁定) { 每頁= maximumRows; int newPageIndex =(startRowIndex/PageSize); (PageIndex!= newPageIndex) { OnPageIndexChanging(new GridViewPageEventArgs(newPageIndex)); PageIndex = newPageIndex; OnPageIndexChanged(EventArgs.Empty); } } RequiresDataBinding = databind; } 當DataPager發送網格的分頁信息時,網格需要自己設置任何適當的參數以準備綁定到正確的數據窗口。網格已經配備的2個屬性是PageSize和PageIndex屬性。這些屬性可以通過發送到方法的信息來計算,所以我們設置它們。當然,如果頁面正在更改,我們可能應該觸發OnPageIndexChanging事件。這意味着如果你沒有綁定到數據源,你仍然需要確保處理這個事件。最後,如果DataPager處於綁定數據的過程中,我們會指示網格重新綁定。這是一個基本的實現,因此您還需要在此處執行任何數據完整性檢查,例如檢查以確保新的PageIndex和StartRowIndex值位於有效範圍內。

只有一件事可以完成我們的GridView到DataPager的集成。爲了讓DataPager呈現適當數量的頁面按鈕,或者讓它知道何時禁用尋呼機上的下一頁或上一頁按鈕,它需要知道總共有多少行。這與DataPager本身聲明指定的頁面大小相結合,可以幫助確定數據源包含的頁面數量。問題是,這些信息並不爲傳呼機所知。然而,GridView已知它,我們需要從那裏獲取它並將其傳遞給DataPager。但是,我們什麼時候才能確定GridView具有這些數據? GridView控件繼承自CompositeDataboundControl。此類型包含CreateChildControls方法的一個特殊變體,該方法還包含一個屬性,用於指示控件是綁定到數據還是簡單地重新渲染。有點反思表明,GridView使用此方法綁定到其數據源。知道這一點,看起來這是我們要注入觸發器的地方,以便引發TotalRowCountAvailable事件。這會變得有點複雜,因爲我們需要處理手動綁定到數據源或使用像ObjectDataSource或SqlDataSource這樣的數據源控件的情況,這些數據源具有在其中指定的總行數。需要一對夫婦的輔助方法,以確保我們得到正確的值:

//Gets row count from SqlDataSource and the like... 
private int _GetTotalRowsFromDataSourceObject(IEnumerable dataSource) 
{ 
    DataSourceView view = this.GetData(); if (AllowPaging && view.CanPage && view.CanRetrieveTotalRowCount) 
     return base.SelectArguments.TotalRowCount; 
    else 
     return (PageIndex * PageSize) + _GetSourceCount(dataSource); 
} 
//Gets the row count from a manually bound source or from a source in viewstate 
private int _GetSourceCount(IEnumerable dataSource) 
{ 
    ICollection source = dataSource as ICollection; 
    return source != null ? 
     source.Count : 
     (from x in dataSource.OfType<object>() select 1).Sum(); 
} 

的_GetTotalRowsFromDataSourceObject方法從數據源對象檢索的記錄的總數,如果它是可用的。這取決於幾件事情,比如EnablePaging屬性是否設置在DataSource控件上以及對象是否已完成查詢操作。最糟糕的情況是,我們返回一頁數據並完成它。 _GetSourceCount方法用於兩個特定的場合。首先,在手動綁定網格的DataSource屬性然後調用DataBind()的情況下,如何獲取行數。其次,當網格在回傳到存儲在視圖狀態中的數據後重新綁定時,這種方法也將證明是有用的。在這兩種情況下,我們都使用一些linq來提取數據源中結果數據項的總數(或視圖狀態下的行)。現在,讓我們看看如何使用這些方法來將其結合在一起:

protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding) 
    { 
     int baseResult = base.CreateChildControls(dataSource, dataBinding); 
     if (dataSource != null) 
     { 
      int dataSourceCount = (IsBoundUsingDataSourceID && dataBinding) ? 
       _GetTotalRowsFromDataSource(dataSource) : 
       _GetSourceCount(dataSource); 
      OnTotalRowCountAvailable(new PageEventArgs(StartRowIndex, MaximumRows, dataSourceCount)); 
     } 
     return baseResult; 
    } 

基站控制的CreateChildControls方法首先被調用,因爲網格使用它實際做數據綁定。如果沒有要綁定的數據,就沒有理由通知尋呼機,所以我們檢查以確保我們有數據,然後通過上述過程確定數據源中的行數。最後,我們使用派生數據來引發事件,然後返回原始結果,以免影響可能依賴它的任何其他操作。我們現在有了一個可以與新的DataPager控件耦合的GridView。這裏的標記,我們會用一個頁面上使用這些控件一起樣本:

<asp:DataPager ID="DataPager1" runat="server" PageSize="2" PagedControlID="grid2"> 
    <Fields> 
     <asp:NextPreviousPagerField /> 
    </Fields> 
</asp:DataPager> 

<custom:pageablegridview id="grid2" runat="server" autogeneratecolumns="true" allowpaging="true" 
     onpageindexchanging="grid2_PageIndexChanging" /> 

請注意,我沒有指定GridView控件的PageSize屬性,因爲在DataPager的PageSize屬性將在控制這個值。爲了確保這一點,我們可以在網格上隱藏PageSize屬性,但現在就足夠了。所以這就是它的全部。對於綁定到數據的新創建的服務器控件,使這些入侵允許您的控件使用DataPager非常簡單。對於像GridView這樣的現有控件,只需要知道綁定是如何發生的,然後將功能注入到某個知道需要的值存在的地方。

2

另一種解決方案更簡單:

  1. 創建一個空表,並給它一個ID。在我的情況下,customPager
  2. 給你默認的GridView尋呼機一個css風格你只需要一個名稱沒有css編碼
  3. 包括jQuery的在您的aspx(頭部分)。
  4. 你看,兩行腳本的下面......那些移動的默認尋呼,你把customPager

這是我能產生最簡單的外...希望它幫助。 ..

<table id="customPager"> 

    </table> 
    <hr /> 
     <div id="dvGridView" style="height: 200px;overflow:scroll;"> 
     <asp:GridView ID="GridView1" runat="server" AllowPaging="True" PageSize="5"> 
      <PagerSettings Position="Top" /> 
      <PagerStyle CssClass="pagerStyle" /> 
     </asp:GridView> 
    </div> 
    <script> 
     $('#customPager').html($('.pagerStyle').html()); 
     $('.pagerStyle').html(''); 
    </script> 
+0

你的把戲看起來不錯,但不幸的是,我會提供一個解決方案,並在幾分鐘前實現 – Nahum

+0

我很高興你解決了你的問題,謝謝你的觀點... – erichste