我在许多网站上看到了关于扩展gridview控件的线程,所以很明显这将是重复的。但我还没有发现任何真正扩展控件的程度,你可以进行自定义排序(使用标题图像),通过在标题列中放置下拉列表或文本框(逐列)和自定义分页(一个它不返回所有记录,只返回给定页面请求的记录)。
是否有任何好的教程可以显示gridview的内部工作原理以及如何覆盖正确的函数?我在这里和那里看到了几个片段,但似乎没有一个真正起作用并且解释得很好。
任何链接都将不胜感激。谢谢!
答案 0 :(得分: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 = " ";
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 = " ";
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);
}
}
}
由于服务器控件很复杂,我无法真正与您交谈,我希望它能为您提供一些帮助。