扩展GridView实现的一个自定义无刷新分页,排序,支持多种数据源的控件TwfGridView
2014-07-09 16:23
881 查看
最近项目View层越来越趋向于无刷新化,特别是数据展示方面,还要对Linq有很好的支持.
在WebFrom模式的开发中,GridView是一个功能很强大,很常用的控件,但是他也不是完美的,没有自带的无刷新和排序(有人说UpdatePanel或第三方插件就可以实现无刷新,但是呵呵...那是重量级的无刷新实现,相信不少朋友和我一样讨厌UpdatePanel,
引入一大堆很长的js库且不说,用起来感觉不到一点无刷新带来的快速),也不支持部分数据绑定分页(有人说部分数据绑定也可以用aspNetPager等第三方插件很好的实现,但是那个插件能在一个事件里搞定分页和排序吗,还是无刷新的),
我也网上找了很多,但都不是很好用,很多还不提供源代码,所以自己实现了一个
具体功能如下:
1.由于是扩展实现.net中自带的GridView 所以GridView的功能她都有
2.支持部分数据绑定,节约服务器资源(即DataSource只需指定当前要显示页的数据,而不需要像自带的GridView一样DataSource为整个数据源)
3.无刷新分页,可自定义分页栏,分页按钮样式
4.无刷新排序,可自定义排序栏,排序按钮的样式
5.自定义无刷新操作后的视图状态[ViewState](1.禁用视图状态 2.只维护数据的视图状态 3.维护全部数据和子控件的视图状态)
6.简化事件处理,排序和分页只需一个事件
下载地址:http://files.cnblogs.com/dint/TComponentsTest_V_1_0_3.rar
不同数据源的绑定:
DataTable:
List,Linq:
分页排序事件,部分数据源(EntityFramework数据操作,其他的类似):
快捷设计时:
分页排序效果:
当前焦点行颜色效果:
下拉页选择效果:
具体实现原理:
1.重写DataSource属性 适应不同数据源
2.重写控件呈现函数 呈现的时候传递分页参数
3.处理ViewState让无刷新之后也能保存视图状态(此处用 IL 实现效率会更高)
4.更友好的设计时支持 让控件更易用
在WebFrom模式的开发中,GridView是一个功能很强大,很常用的控件,但是他也不是完美的,没有自带的无刷新和排序(有人说UpdatePanel或第三方插件就可以实现无刷新,但是呵呵...那是重量级的无刷新实现,相信不少朋友和我一样讨厌UpdatePanel,
引入一大堆很长的js库且不说,用起来感觉不到一点无刷新带来的快速),也不支持部分数据绑定分页(有人说部分数据绑定也可以用aspNetPager等第三方插件很好的实现,但是那个插件能在一个事件里搞定分页和排序吗,还是无刷新的),
我也网上找了很多,但都不是很好用,很多还不提供源代码,所以自己实现了一个
具体功能如下:
1.由于是扩展实现.net中自带的GridView 所以GridView的功能她都有
2.支持部分数据绑定,节约服务器资源(即DataSource只需指定当前要显示页的数据,而不需要像自带的GridView一样DataSource为整个数据源)
3.无刷新分页,可自定义分页栏,分页按钮样式
4.无刷新排序,可自定义排序栏,排序按钮的样式
5.自定义无刷新操作后的视图状态[ViewState](1.禁用视图状态 2.只维护数据的视图状态 3.维护全部数据和子控件的视图状态)
6.简化事件处理,排序和分页只需一个事件
下载地址:http://files.cnblogs.com/dint/TComponentsTest_V_1_0_3.rar
不同数据源的绑定:
DataTable:
private void BindSource() { DataTable dtPersons = new DataTable(); dtPersons.Columns.Add("Name"); dtPersons.Columns.Add("Age"); dtPersons.Columns.Add("Address"); dtPersons.Columns.Add("Sex"); for (int i = 1, il = 5000; i <= il; i++) { DataRow nrow = dtPersons.NewRow(); nrow[0] = "Name" + i.ToString(); nrow[1] = "Age" + i.ToString(); nrow[2] = "Address" + i.ToString(); nrow[3] = "Sex" + i.ToString(); dtPersons.Rows.Add(nrow); } TwfGridView1.DataSource = dtPersons; TwfGridView1.DataBind(); }
List,Linq:
private void BindSource() { List<Person> lstPersons = new List<Person>(); for (int i = 1, il = 2000; i <= il; i++) { Person p = new Person() { Id=i, Name = "Name" + i.ToString(), Age = "Age" + i.ToString(), Address = "Address" + i.ToString(), Sex = "Sex" + i.ToString() }; lstPersons.Add(p); } TwfGridView1.DataSource = lstPersons; TwfGridView1.DataBind(); }
分页排序事件,部分数据源(EntityFramework数据操作,其他的类似):
//部分数据源绑定需调用,重载的DataBind(int pageIndex,int allRecordCount)方法
private void DataBinder(int pageindex, string sortexp, SortDirection? direct) { using (var db = new EFDbContext(@"Data Source=.;Initial Catalog=dbtest;Integrated Security=true;")) { var results = db.Persons.Where(x => x.Id < 500); int rc = results.Count(); int ps = (rc % TwfGridView1.PageSize == 0) ? rc / TwfGridView1.PageSize : rc / TwfGridView1.PageSize + 1; if (pageindex > ps - 1) pageindex = ps - 1; var v= results; if (sortexp == "Id") { if (direct == SortDirection.Descending) { v = v.OrderByDescending(x => x.Id); } else { v = v.OrderBy(x => x.Id); } } else if (sortexp == "Name") { if (direct == SortDirection.Descending) { v = v.OrderByDescending(x => x.Name); } else { v = v.OrderBy(x => x.Name); } } else if (sortexp == "Age") { if (direct == SortDirection.Descending) { v = v.OrderByDescending(x => x.Age); } else { v = v.OrderBy(x => x.Age); } } else if (sortexp == "Sex") { if (direct == SortDirection.Descending) { v = v.OrderByDescending(x => x.Sex); } else { v = v.OrderBy(x => x.Id); } } else if (sortexp == "Address") { if (direct == SortDirection.Descending) { v = v.OrderByDescending(x => x.Address); } else { v = v.OrderBy(x => x.Address); } } else { v = v.OrderBy(x => x.Id); } v = v.Skip(pageindex * TwfGridView1.PageSize).Take(TwfGridView1.PageSize); TwfGridView1.DataSource =v.ToList(); TwfGridView1.DataBind(pageindex, rc);//注意重载了DataBind方法 } } protected void TwfGridView1_PageSorting(object sender, GridViewPageEventArgs ePage, Dint.TwfWebox.EGridViewSortArgs eSort) { DataBinder(ePage.NewPageIndex, eSort.SortExpression, eSort.SortDirection); }
<cc1:TwfGridView ID="TwfGridView1" runat="server" onpagesorting="TwfGridView1_PageSorting" AjaxViewState="False" AllowPaging="True" AllowSorting="True" FocusBgColor="" jQuerySupport="True" LoadMsg="正在加载数据..."> <EPagerSetting NavButton="PrevNumNext" ClassName="TwfGv_All" NavMessageBarCss="TwfGv_NavMessage" NumBtnBarCss="TwfGv_NumBtnBar" CurrentNumBtnCss="TwfGv_CurrNumBtn" PrevNextBtnCss="TwfGv_PrevNextBtn" DisabledPrevNextBtnCss="TwfGv_PrevNextDisable" PagerInfoFormatter="<每页 {RecordCount} 条 共 {TotalCount} 条 当前第 {PageIndex}/{PageCount} 页>" GoToBarEnable="True" GotoBtnText="转到" GoToDropdown="DropdownSubmit" GotoClassName="TwfGv_Goto" GotoTxtCss="TwfGv_Goto_Txt"></EPagerSetting> <ESortSetting SortAscCss="TwfGv_SortAsc" SortDescCss="TwfGv_SortDesc" SortDefaultCss="TwfGv_SortDef" AscFormatter="{0}↑" DescFormatter="{0}↓"></ESortSetting> <PagerSettings FirstPageText="首页" LastPageText="末页" NextPageText="下一页" PreviousPageText="上一页"></PagerSettings> </cc1:TwfGridView>
快捷设计时:
分页排序效果:
当前焦点行颜色效果:
下拉页选择效果:
具体实现原理:
1.重写DataSource属性 适应不同数据源
/// <summary> /// 获取或设置数据源 支持 DataTable,DataView,ICollection,ITwfRecordCount,IQueryable 等类型的数据源 /// </summary> public override object DataSource { get { return base.DataSource; } set { IListSource dtSource = value as IListSource; if (dtSource != null){ _RecordCount = dtSource.GetList().Count; } else{ ITwfRecordCount trcSource = value as ITwfRecordCount; if (trcSource != null){ _RecordCount = trcSource.RecordCount(); } else{ ICollection cletSource = value as ICollection; if (cletSource != null){ _RecordCount = cletSource.Count; } else{ IEnumerable aEnum = value as IEnumerable; if (aEnum != null) { IEnumerator aEnumtor = aEnum.GetEnumerator(); if (aEnumtor != null) { int iCount = 0; aEnumtor.Reset(); while (aEnumtor.MoveNext())iCount++; _RecordCount = iCount; } } } } } VsRecordCount = _RecordCount; base.DataSource = value; } }
2.重写控件呈现函数 呈现的时候传递分页参数
private void RenderHtml(HtmlTextWriter defWriter) { if (Page != null) { Page.VerifyRenderingInServerForm(this); StringBuilder strBuilder = new StringBuilder(2048); StringWriter strWriter = new StringWriter(strBuilder); HtmlTextWriter htmlWriter = new HtmlTextWriter(strWriter); base.RenderChildren(htmlWriter); string strVs="",strEvl=""; TransferFormState(ref strVs, ref strEvl); RspCallBackResult(string.Format("SUCCE{0},{1},{2},{3}~{4},{5},{6}~{8}~{9}~{7}", PageIndex.ToString().PadLeft(4, '0'), PageCount.ToString().PadLeft(4, '0'), "0000", "0000",aSort.ColumnIndex.ToString(), aSort.SortExpression,aSort.DirectString,strBuilder.ToString(),strVs,strEvl)); } else{ base.RenderChildren(defWriter); } }
3.处理ViewState让无刷新之后也能保存视图状态(此处用 IL 实现效率会更高)
private void TransferFormState(ref string rVstate,ref string rEvl) { if (_AjaxViewState && isVsSupport) { MethodInfo ptrM = Page.GetType().GetMethod("DecomposeViewStateIntoChunks", BindingFlags.Instance | BindingFlags.NonPublic); ICollection ivs = ptrM.Invoke(Page, null) as ICollection; if ((ivs != null) && (ivs.Count > 0)) { StringBuilder strBuilder = new StringBuilder(1024); int num = 0, ivc = ivs.Count - 1; foreach (string s in ivs) { strBuilder.Append(s); if (num < ivc) strBuilder.Append("#"); num++; } rVstate = strBuilder.ToString(); } if (Page.EnableEventValidation) { ptrM = Page.ClientScript.GetType().GetMethod("GetEventValidationFieldValue", BindingFlags.Instance | BindingFlags.NonPublic); rEvl = ((ptrM.Invoke(Page.ClientScript, null) as string) ?? ""); } } }
4.更友好的设计时支持 让控件更易用
public class TwfGridDesignerActionList : DesignerActionList { private TwfGridView twfGridView; public TwfGridDesignerActionList(IComponent component) : base(component) { twfGridView = component as TwfGridView; } private void SetProperty(string propertyName, object value) { TypeDescriptor.GetProperties(twfGridView)[propertyName].SetValue(twfGridView, value); } public override DesignerActionItemCollection GetSortedActionItems() { DesignerActionItemCollection nitem = new DesignerActionItemCollection(); nitem.Add(new DesignerActionHeaderItem("扩展分页/排序", "kzfypx")); nitem.Add(new DesignerActionPropertyItem("AllowPaging", "允许分页", "kzfypx")); nitem.Add(new DesignerActionPropertyItem("AllowSorting", "允许排序", "kzfypx")); nitem.Add(new DesignerActionPropertyItem("GotoEnable", "启用'转到'按钮", "kzfypx")); nitem.Add(new DesignerActionPropertyItem("StateMode", "视图状态", "kzfypx", "Part:部分状态\r\nNone:无状态\r\nAll:完全状态")); nitem.Add(new DesignerActionMethodItem(this, "About", "关于 TwfGridView ...", "kzfypx",true)); return nitem; } [EditorBrowsable(EditorBrowsableState.Never)] public bool GotoEnable { get{ return this.twfGridView.EPagerSetting.GoToBarEnable; } set { TypeDescriptor.GetProperties(twfGridView.EPagerSetting)["GoToBarEnable"].SetValue(twfGridView.EPagerSetting,value); AllowPaging = AllowPaging; } } [EditorBrowsable(EditorBrowsableState.Never)] public void About() { (new FrmAbout()).ShowDialog(); } [EditorBrowsable(EditorBrowsableState.Never)] public bool AllowSorting { get { return this.twfGridView.AllowSorting; } set { SetProperty("AllowSorting", value); } } [EditorBrowsable(EditorBrowsableState.Never)] public bool AllowPaging { get { return this.twfGridView.AllowPaging; } set { SetProperty("AllowPaging", value); } } [EditorBrowsable(EditorBrowsableState.Never)] public TwfGridViewStateMode StateMode { get { if (!this.twfGridView.EnableViewState) return TwfGridViewStateMode.None; if (!this.twfGridView.AjaxViewState) return TwfGridViewStateMode.Part; return TwfGridViewStateMode.All; } set { switch (value) { case TwfGridViewStateMode.None: SetProperty("EnableViewState", false); SetProperty("AjaxViewState", false); break; case TwfGridViewStateMode.Part: SetProperty("EnableViewState", true); SetProperty("AjaxViewState", false); break; case TwfGridViewStateMode.All: SetProperty("EnableViewState", true); SetProperty("AjaxViewState", true); break; default: throw new Exception("error param"); } } } }
相关文章推荐
- GridView 实现自定义分页、排序、查询、添加、编辑、多选删除
- 一个自定义的可以分页,排序,扩展显示grid控件
- GridView控件自定义分页的实现
- 扩展GridView控件以包含一个与排序相关的箭头标记
- jquery+ashx无刷新GridView数据显示插件(实现分页、排序、过滤功能)
- 新写的一个使用ASP.NET AJAX中的UpdatePanel控件实现GridView的无刷新删除,更新,添加,查询!
- GridView 实现自定义分页、排序、查询、添加、编辑、多选删除 之代码规范
- GridView控件实现支持分页的自动编号代码
- 一个集成自定义分页和列可拖动的GridView控件
- GridView 实现自定义分页、排序、查询、添加、编辑、多选删除、导出、突出显示等常见应用实现
- 扩展GridView控件(10) - 自定义分页样式
- GridView 实现自定义分页、排序、查询、添加、编辑、多选删除
- 扩展GridView控件(10) - 自定义分页样式
- 扩展GridView控件(10) - 自定义分页样式
- gridview 实现自定义分页、排序、查询、添加、编辑、多选删除 之代码规范
- GridView 实现自定义分页、排序、查询、添加、编辑、多选删除 之代码规范
- 5.1奉献【源码】一个集成自定义分页和列可拖动的GridView控件
- 扩展GridView控件(10) - 自定义分页样式
- 使用RedControls控件RadAjaxPanel、AjaxLoadingPanel实现GridView无刷新翻页和排序