【问题标题】:Problem with Efficient Gridview paging without datasource control没有数据源控制的高效 Gridview 分页问题
【发布时间】:2011-01-31 21:59:05
【问题描述】:

我正在尝试在不使用数据源控件的情况下使用 gridview 进行有效的分页。高效,我的意思是我只检索我打算显示的记录。

我正在尝试使用 PagerTemplate 来构建我的寻呼机功能。

简而言之,问题是如果我只绑定我打算在当前页面上显示的记录,gridview 不会呈现它的分页器模板,所以我没有得到分页控件。

就好像我必须绑定比我打算在给定页面上显示的更多的记录,这不是我想做的事情。

【问题讨论】:

    标签: c# .net asp.net gridview pagination


    【解决方案1】:

    您需要创建一个继承自 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();
    

    【讨论】:

    • 真的吗?这是这类问题的“解决方案”吗?我知道这不是你的错 clyc。我无法想象这是最好的方法。我想我最好只在gridview下面粘贴一些控件。
    • 你的gridview之所以不显示分页控件是因为它只知道你绑定到控件的记录数,而不知道潜在记录的总数。如果您不想创建自定义网格视图,另一种方法是在网格视图底部创建一个单独的控件,用于处理获取您可能返回的项目总数并计算用户可以访问的页面数通过。
    • 谢谢。我只是希望有一个技巧或我遗漏的东西。如果gridview上有一个公共可写属性来设置记录总数,似乎会简单得多。
    • 是的,罗尼。这个公共属性是 gridview 中缺少的,因此我们必须创建一个自定义的 gridview 来公开它:)
    • 感谢您的提示。它工作正常,除了在最后一页上插入一行时发生的一个问题,新行应显示在下一页上。它抛出这样的视图状态错误。 "Sys.WebForms.PageRequestManagerServerErrorException: 加载视图状态失败。正在加载视图状态的控件树必须与上一次请求期间用于保存视图状态的控件树匹配。例如,动态添加控件时,在回发必须与初始请求期间添加的控件的类型和位置相匹配。"?
    猜你喜欢
    • 1970-01-01
    • 2013-02-12
    • 2011-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多