【问题标题】:ASP.NET - Extend gridview to allow filtering, sorting, paging, etcASP.NET - 扩展 gridview 以允许过滤、排序、分页等
【发布时间】:2010-04-30 02:32:42
【问题描述】:

我在许多网站上看到了有关扩展 gridview 控件的主题,因此很明显这将是重复的。但是我还没有发现任何真正将控件扩展到可以自定义排序(带有标题图像),通过在标题列中放置下拉列表或文本框(逐列)和自定义分页(一个这不会返回所有记录,而只会返回给定页面请求的记录)。

是否有任何好的教程可以展示 gridview 的内部工作原理以及如何覆盖正确的功能?我在这里和那里看到过几个 sn-ps,但似乎没有一个能真正起作用并很好地解释事情。

任何链接将不胜感激。谢谢!

【问题讨论】:

    标签: c# .net asp.net gridview


    【解决方案1】:

    我自己扩展了 GridView 控件,以允许使用图像进行排序、自定义分页(因此您可以从下拉列表中选择每页的记录数)和其他一些东西。但是,您将无法执行仅返回所请求页面的记录的自定义分页,因为这是您的数据源需要处理的内容,而不是 GridView。

    我真正能做的就是给你一些代码,希望对你有帮助。这是相当旧的代码(C#3.0 之前),但可能有一些用处:

    首先是扩展标准 GridView 的自定义 GridView 控件:

    using System;
    using System.Collections;
    using System.Drawing;
    using System.Web.UI.WebControls;
    using Diplo.WebControls.DataControls.PagerTemplates;
    using Image=System.Web.UI.WebControls.Image;
    
    namespace Diplo.WebControls.DataControls
    {
        /// <summary>
        /// Extended <see cref="GridView"/> with some additional cool properties
        /// </summary>
        public class DiploGridView : GridView
        {
            #region Properties
    
            /// <summary>
            /// Gets or sets a value indicating whether a sort graphic is shown in column headings
            /// </summary>
            /// <value><c>true</c> if sort graphic is displayed; otherwise, <c>false</c>.</value>
            public bool EnableSortGraphic
            {
                get
                {
                    object o = ViewState["EnableSortGraphic"];
                    if (o != null)
                    {
                        return (bool)o;
                    }
                    return true;
                }
                set
                {
                    ViewState["EnableSortGraphic"] = value;
                }
            }
    
            /// <summary>
            /// Gets or sets the sort ascending image when <see cref="EnableSortGraphic"/> is <c>true</c>
            /// </summary>
            public string SortAscendingImage
            {
                get
                {
                    object o = ViewState["SortAscendingImage"];
                    if (o != null)
                    {
                        return (string)o;
                    }
                    return Page.ClientScript.GetWebResourceUrl(GetType(), SharedWebResources.ArrowUpImage);
                }
                set
                {
                    ViewState["SortAscendingImage"] = value;
                }
            }
    
            /// <summary>
            /// Gets or sets the sort descending image <see cref="EnableSortGraphic"/> is <c>true</c>
            /// </summary>
            public string SortDescendingImage
            {
                get
                {
                    object o = ViewState["SortDescendingImage"];
                    if (o != null)
                    {
                        return (string)o;
                    }
                    return Page.ClientScript.GetWebResourceUrl(GetType(), SharedWebResources.ArrowDownImage);
                }
                set
                {
                    ViewState["SortDescendingImage"] = value;
                }
            }
    
            /// <summary>
            /// Gets or sets the custom pager settings mode.
            /// </summary>
            public CustomPagerMode CustomPagerSettingsMode
            {
                get
                {
                    object o = ViewState["CustomPagerSettingsMode"];
                    if (o != null)
                    {
                        return (CustomPagerMode)o;
                    }
                    return CustomPagerMode.None;
                }
                set
                {
                    ViewState["CustomPagerSettingsMode"] = value;
                }
            }
    
            /// <summary>
            /// Gets or sets a value indicating whether the columns in the grid can be re-sized in the UI
            /// </summary>
            /// <value><c>true</c> if  column resizing is allowed; otherwise, <c>false</c>.</value>
            public bool AllowColumnResizing
            {
                get
                {
                    object o = ViewState["AllowColumnResizing"];
                    if (o != null)
                    {
                        return (bool)o;
                    }
                    return false;
                }
                set
                {
                    ViewState["AllowColumnResizing"] = value;
                }
            }
    
            /// <summary>
            /// Gets or sets the highlight colour for the row
            /// </summary>
            public Color RowStyleHighlightColour
            {
                get
                {
                    object o = ViewState["RowStyleHighlightColour"];
                    if (o != null)
                    {
                        return (Color)o;
                    }
                    return Color.Empty;
                }
                set
                {
                    ViewState["RowStyleHighlightColour"] = value;
                }
            }
    
            #endregion Properties
    
            #region Enums
    
            /// <summary>
            /// Represents additional custom paging modes
            /// </summary>
            public enum CustomPagerMode
            {
                /// <summary>
                /// No custom paging mode
                /// </summary>
                None,
                /// <summary>
                /// Shows the rows drop-down list <i>and</i> the previous and next buttons
                /// </summary>
                RowsPagePreviousNext,
                /// <summary>
                /// Only shows the previous and next buttons
                /// </summary>
                PagePreviousNext
            }
    
            #endregion
    
            #region Overridden Events
    
            /// <summary>
            /// Initializes the pager row displayed when the paging feature is enabled.
            /// </summary>
            /// <param name="row">A <see cref="T:System.Web.UI.WebControls.GridViewRow"></see> that represents the pager row to initialize.</param>
            /// <param name="columnSpan">The number of columns the pager row should span.</param>
            /// <param name="pagedDataSource">A <see cref="T:System.Web.UI.WebControls.PagedDataSource"></see> that represents the data source.</param>
            protected override void InitializePager(GridViewRow row, int columnSpan, PagedDataSource pagedDataSource)
            {
                switch (CustomPagerSettingsMode)
                {
                    case CustomPagerMode.RowsPagePreviousNext:
                        PagerTemplate = new RowsPagePreviousNext(pagedDataSource, this);
                        break;
                    case CustomPagerMode.PagePreviousNext:
                        PagerTemplate = new PagePreviousNext(pagedDataSource, this);
                        break;
                    case CustomPagerMode.None:
                        break;
                    default:
                        break;
                }
    
                base.InitializePager(row, columnSpan, pagedDataSource);
            }
    
            /// <summary>
            /// Raises the <see cref="E:System.Web.UI.Control.PreRender"></see> event.
            /// </summary>
            /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
            protected override void OnPreRender(EventArgs e)
            {
                if (AllowColumnResizing && Visible)
                {
                    string vars = String.Format("var _DiploGridviewId = '{0}';\n", ClientID);
    
                    if (!Page.ClientScript.IsClientScriptBlockRegistered("Diplo_GridViewVars"))
                    {
                        Page.ClientScript.RegisterClientScriptBlock(GetType(), "Diplo_GridViewVars", vars, true);
                    }
    
                    Page.ClientScript.RegisterClientScriptInclude("Diplo_GridView.js",
                                                                  Page.ClientScript.GetWebResourceUrl(GetType(), "Diplo.WebControls.SharedWebResources.Diplo_GridView_Resize.js"));
                }
    
                base.OnPreRender(e);
            }
    
            /// <summary>
            /// Raises the <see cref="E:System.Web.UI.WebControls.GridView.RowCreated"></see> event.
            /// </summary>
            /// <param name="e">A <see cref="T:System.Web.UI.WebControls.GridViewRowEventArgs"></see> that contains event data.</param>
            protected override void OnRowCreated(GridViewRowEventArgs e)
            {
                if (EnableSortGraphic)
                {
                    if (!((e.Row == null)) && e.Row.RowType == DataControlRowType.Header)
                    {
                        foreach (TableCell cell in e.Row.Cells)
                        {
                            if (cell.HasControls())
                            {
                                LinkButton button = ((LinkButton)(cell.Controls[0]));
                                if (!((button == null)))
                                {
                                    Image image = new Image();
                                    image.ImageUrl = "images/default.gif";
                                    image.ImageAlign = ImageAlign.Baseline;
                                    if (SortExpression == button.CommandArgument)
                                    {
                                        image.ImageUrl = SortDirection == SortDirection.Ascending ? SortAscendingImage : SortDescendingImage;
                                        Literal space = new Literal();
                                        space.Text = "&nbsp;";
                                        cell.Controls.Add(space);
                                        cell.Controls.Add(image);
                                    }
                                }
                            }
                        }
                    }
                }
    
                if (RowStyleHighlightColour != Color.Empty)
                {
                    if (e.Row != null)
                    {
                        if (e.Row.RowType == DataControlRowType.DataRow)
                        {
                            e.Row.Attributes.Add("onmouseover", String.Format("this.style.backgroundColor='{0}'", ColorTranslator.ToHtml(RowStyleHighlightColour)));
                            e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor=''");
                        }
                    }
                }
    
                base.OnRowCreated(e);
            }
    
            /// <summary>
            /// Creates the control hierarchy that is used to render a composite data-bound control based on the values that are stored in view state.
            /// </summary>
            protected override void CreateChildControls()
            {
                base.CreateChildControls();
    
                CheckShowPager();
            }
    
            private void CheckShowPager()
            {
                if (CustomPagerSettingsMode != CustomPagerMode.None && AllowPaging)
                {
                    if (TopPagerRow != null)
                    {
                        TopPagerRow.Visible = true;
                    }
    
                    if (BottomPagerRow != null)
                    {
                        BottomPagerRow.Visible = true;
                    }
                }
            }
    
            /// <summary>
            /// Creates the control hierarchy used to render the <see cref="T:System.Web.UI.WebControls.GridView"></see> control using the specified data source.
            /// </summary>
            /// <param name="dataSource">An <see cref="T:System.Collections.IEnumerable"></see> that contains the data source for the <see cref="T:System.Web.UI.WebControls.GridView"></see> control.</param>
            /// <param name="dataBinding">true to indicate that the child controls are bound to data; otherwise, false.</param>
            /// <returns>The number of rows created.</returns>
            protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding)
            {
                int i = base.CreateChildControls(dataSource, dataBinding);
    
                CheckShowPager();
    
                return i;
            }
    
        #endregion Overridden Events
    }
    }
    

    然后有一个自定义的分页类,用作分页模板:

    using System;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;
    using System.Web.UI;
    
    namespace Diplo.WebControls.DataControls.PagerTemplates
    {
        /// <summary>
        /// Paging template for the <see cref="DiploGridView"/>
        /// </summary>
        public class RowsPagePreviousNext : ITemplate
        {
            readonly PagedDataSource _pagedDataSource;
            readonly DiploGridView DiploGridView;
    
            /// <summary>
            /// Initializes a new instance of the <see cref="RowsPagePreviousNext"/> class.
            /// </summary>
            /// <param name="pagedDataSource">The <see cref="PagedDataSource"/>.</param>
            /// <param name="DiploGrid">A reference to the <see cref="DiploGridView"/>.</param>
            public RowsPagePreviousNext(PagedDataSource pagedDataSource, DiploGridView DiploGrid)
            {
                _pagedDataSource = pagedDataSource;
                DiploGridView = DiploGrid;
            }
    
            /// <summary>
            /// When implemented by a class, defines the <see cref="T:System.Web.UI.Control"></see> object that child controls and templates belong to. These child controls are in turn defined within an inline template.
            /// </summary>
            /// <param name="container">The <see cref="T:System.Web.UI.Control"></see> object to contain the instances of controls from the inline template.</param>
            void ITemplate.InstantiateIn(Control container)
            {
                Literal space = new Literal();
                space.Text = "&nbsp;";
    
                HtmlGenericControl divLeft = new HtmlGenericControl("div");
                divLeft.Style.Add("float", "left");
                divLeft.Style.Add(HtmlTextWriterStyle.Width, "25%");
    
                Label lb = new Label();
                lb.Text = "Show rows: ";
                divLeft.Controls.Add(lb);
    
                DropDownList ddlPageSize = new DropDownList();
                ListItem item;
                ddlPageSize.AutoPostBack = true;
                ddlPageSize.ToolTip = "Select number of rows per page";
    
                int max = (_pagedDataSource.DataSourceCount < 50) ? _pagedDataSource.DataSourceCount : 50;
                int i;
                const int increment = 5;
                bool alreadySelected = false;
                for (i = increment; i <= max; i = i + increment)
                {
                    item = new ListItem(i.ToString());
                    if (i == _pagedDataSource.PageSize)
                    {
                        item.Selected = true;
                        alreadySelected = true;
                    }
                    ddlPageSize.Items.Add(item);
                }
    
                item = new ListItem("All", _pagedDataSource.DataSourceCount.ToString());
                if (_pagedDataSource.DataSourceCount == _pagedDataSource.PageSize && alreadySelected == false)
                {
                    item.Selected = true;
                    alreadySelected = true;
                }
    
                if (_pagedDataSource.DataSourceCount > (i - increment) && alreadySelected == false)
                {
                    item.Selected = true;
                }
    
                ddlPageSize.Items.Add(item);
    
                ddlPageSize.SelectedIndexChanged += new EventHandler(ddlPageSize_SelectedIndexChanged);
    
                divLeft.Controls.Add(ddlPageSize);
    
                HtmlGenericControl divRight = new HtmlGenericControl("div");
                divRight.Style.Add("float", "right");
                divRight.Style.Add(HtmlTextWriterStyle.Width, "75%");
                divRight.Style.Add(HtmlTextWriterStyle.TextAlign, "right");
    
                Literal lit = new Literal();
                lit.Text = String.Format("Found {0} record{1}. Page ", 
                    _pagedDataSource.DataSourceCount, 
                    (_pagedDataSource.DataSourceCount == 1) ? String.Empty : "s" );
                divRight.Controls.Add(lit);
    
                TextBox tbPage = new TextBox();
                tbPage.ToolTip = "Enter page number";
                tbPage.Columns = 2;
                tbPage.MaxLength = 3;
                tbPage.Text = (_pagedDataSource.CurrentPageIndex + 1).ToString();
                tbPage.CssClass = "pagerTextBox";
                tbPage.AutoPostBack = true;
                tbPage.TextChanged += new EventHandler(tbPage_TextChanged);
                divRight.Controls.Add(tbPage);
                if (_pagedDataSource.PageCount < 2)
                    tbPage.Enabled = false;
    
                lit = new Literal();
                lit.Text = " of " + _pagedDataSource.PageCount;
                divRight.Controls.Add(lit);
    
                divRight.Controls.Add(space);
    
                Button btn = new Button();
                btn.Text = "";
                btn.CommandName = "Page";
                btn.CommandArgument = "Prev";
                btn.SkinID = "none";
                btn.Enabled = !_pagedDataSource.IsFirstPage;
                btn.CssClass = (btn.Enabled) ? "buttonPreviousPage" : "buttonPreviousPageDisabled";
                if (btn.Enabled)
                    btn.ToolTip = "Previous page";
                divRight.Controls.Add(btn);
    
                btn = new Button();
                btn.Text = "";
                btn.CommandName = "Page";
                btn.CommandArgument = "Next";
                btn.SkinID = "none";
                btn.CssClass = "buttonNext";
                btn.Enabled = !_pagedDataSource.IsLastPage;
                btn.CssClass = (btn.Enabled) ? "buttonNextPage" : "buttonNextPageDisabled";
                if (btn.Enabled)
                    btn.ToolTip = "Next page";
                divRight.Controls.Add(btn);
    
                container.Controls.Add(divLeft);
                container.Controls.Add(divRight);
            }
    
            /// <summary>
            /// Handles the TextChanged event of the tbPage control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
            void tbPage_TextChanged(object sender, EventArgs e)
            {
                TextBox tb = sender as TextBox;
    
                if (tb != null)
                {
                    int page;
                    if (int.TryParse(tb.Text, out page))
                    {
                        if (page <= _pagedDataSource.PageCount && page > 0)
                        {
                            DiploGridView.PageIndex = page - 1;
                        }
                    }
                }
            }
    
            /// <summary>
            /// Handles the SelectedIndexChanged event of the ddlPageSize control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
            void ddlPageSize_SelectedIndexChanged(object sender, EventArgs e)
            {
                DropDownList list = sender as DropDownList;
                if (list != null) DiploGridView.PageSize = Convert.ToInt32(list.SelectedValue);
            }
        }
    }
    

    由于服务器控件很复杂,我无法真正告诉你,我只是希望它能给你一些帮助。

    【讨论】:

    • 很好的例子!我可以使用它并为我自己的项目提取概念。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    • 2012-06-02
    • 2016-12-27
    • 2018-01-13
    • 2018-09-20
    • 2012-11-29
    • 1970-01-01
    相关资源
    最近更新 更多