1

ASP.NET [GridView 的水平滚动] 展示了如何向我的网格添加水平滚动

问题是它还会在自动生成的寻呼机周围滚动。

我可以制作外部寻呼机,但肯定有更好的解决方案吗?

问题是:有没有一种简单的方法可以使我的gridview 水平滚动而不使寻呼机滚动。

4

2 回答 2

2

另一个更简单的解决方案:

  1. 创建一个空表并给它一个id。在我的情况下customPager
  2. 给您的默认 GridView 寻呼机一个css 样式您只需要一个没有 css 编码的名称
  3. 将jquery包含在您的 aspx(头部)中。
  4. 您会看到下面的 2 行脚本...它们将默认分页移到您放置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>
于 2013-01-02T14:33:36.293 回答
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 本身相比,pager 的模板控件非常强大。

让我们从数据绑定控件如何与 DataPager 通信开始。DataPager 控件可以连接到任何实现位于 System.Web.Extensions 程序集中的 IPageableItemContainer 接口的控件。这是 .NET Reflector 提供的界面外观的快速截图:

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 的交互中很重要,因为这是您的控件中的方法,每当您单击任何 DataPagerField 控件(例如,下一个或上一个按钮)时,DataPager 都会调用该方法。最后,该接口定义了一个名为 TotalRowCountAvailable 的事件。此事件告诉 DataPager 绑定到控件的数据中有多少条记录。

因此,让我们开始使用 DataPager 的钩子扩展 GridView。从 GridView 的角度考虑 IPageableItemContainer 接口,我们意识到 MaximumRows 等价于现有的 PageSize 属性,而 StartRowIndex 可以从现有的 PageSize 和 PageIndex 属性中计算出来。我们还通过声明事件并创建相应的事件调用程序来准备事件。因为我希望我的新分页功能成为此网格的默认功能,所以我强制分页器在每次页面加载时隐藏自己。如果您愿意,可以为此行为添加一个切换。最后,我们将 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 方法发挥作用的地方。这是完成工作的基本实现:

protected virtual void SetPageProperties(int startRowIndex, int maximumRows, bool dataBind) { if (databind) { PageSize = maximumRows; int newPageIndex = (startRowIndex / PageSize); if (PageIndex != newPageIndex) { OnPageIndexChanging(new GridViewPageEventArgs(newPageIndex)); 页面索引 = 新页面索引;OnPageIndexChanged(EventArgs.Empty); } } RequiresDataBinding = 数据绑定;当 DataPager 向网格发送其分页信息时,网格需要对其自身设置任何适当的参数以准备绑定到正确的数据窗口。网格已经配备的 2 个属性是 PageSize 和 PageIndex 属性。这些属性可以从发送到方法中的信息中计算出来,所以我们设置它们。当然,如果 Page 正在更改,我们可能应该触发 OnPageIndexChanging 事件。这意味着如果您没有绑定到数据源,您仍然需要确保处理此事件。最后,如果 DataPager 处于绑定数据的过程中,我们会指示网格重新绑定自身。这是一个基本实现,因此您还需要在此处进行任何数据完整性检查,例如检查以确保新的 PageIndex 和 StartRowIndex 值在有效范围内。

完成我们将 GridView 与 DataPager 的集成只剩下一件事要做。为了让 DataPager 呈现适当数量的页面按钮,或者让它知道何时禁用分页器上的下一页或上一页按钮,它需要知道总共有多少行。这与在 DataPager 本身上以声明方式指定的页面大小相结合,有助于确定数据源包含的页面数。问题是,寻呼机不知道这些信息。然而,GridView 知道它,我们需要从那里获取它并将其传递给 DataPager。但是我们什么时候可以确定 GridView 有这些数据呢?GridView 控件继承自 CompositeDataboundControl。此类型包含 CreateChildControls 方法的特殊变体,该变体还接受一个属性,该属性指示控件是绑定到数据还是简单地重新呈现。一点反映表明 GridView 使用此方法绑定到其数据源。知道了这一点,看来这是我们想要注入触发器以引发 TotalRowCountAvailable 事件的地方。这有点复杂,因为我们需要处理手动绑定到数据源或使用 DataSource 控件(如 ObjectDataSource 或 SqlDataSource)的情况,这些控件中指定了总行数。需要几个辅助方法来确保我们获得正确的值:一点反映表明 GridView 使用此方法绑定到其数据源。知道了这一点,看来这是我们想要注入触发器以引发 TotalRowCountAvailable 事件的地方。这有点复杂,因为我们需要处理手动绑定到数据源或使用 DataSource 控件(如 ObjectDataSource 或 SqlDataSource)的情况,这些控件中指定了总行数。需要几个辅助方法来确保我们获得正确的值:一点反映表明 GridView 使用此方法绑定到其数据源。知道了这一点,看来这是我们想要注入触发器以引发 TotalRowCountAvailable 事件的地方。这有点复杂,因为我们需要处理手动绑定到数据源或使用 DataSource 控件(如 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 方法从 DataSource 对象中检索记录的总数(如果可用)。这取决于几件事,例如是否在 DataSource 控件上设置了 EnablePaging 属性以及 Object 是否已完成查询操作。最坏的情况,我们返回一页数据并完成它。_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,只需知道绑定是如何发生的,然后将功能注入到您知道所需值将存在的地方。

于 2013-01-02T14:42:59.537 回答