zoukankan      html  css  js  c++  java
  • 扩展GridView实现的一个自定义无刷新分页,排序,支持多种数据源的控件TwfGridView

    最近项目View层越来越趋向于无刷新化,特别是数据展示方面,还要对Linq有很好的支持.
    在WebFrom模式的开发中,GridView是一个功能很强大,很常用的控件,但是他也不是完美的,没有自带的无刷新和排序(有人说UpdatePanel或第三方插件就可以实现无刷新,呵呵... 相信不少朋友和我一样讨厌UpdatePanel,
    引入一大堆很长的js库且不说,用起来感觉不到一点无刷新带来的快速),也不支持部分数据绑定分页(有人说部分数据绑定也可以用aspNetPager等第三方插件很好的实现,但是那个插件能在一个事件里搞定分页和排序吗,还是无刷新的),
    我也网上找了很多,但都不是很好用,很多还不提供源代码,所以自己实现了一个
    具体功能如下:
    1.由于是扩展实现.net中自带的GridView 所以GridView的功能她都有
    2.支持部分数据绑定,节约服务器资源(即DataSource只需指定当前要显示页的数据,而不需要像自带的GridView一样DataSource为整个数据源)
    3.无刷新分页,可自定义分页栏,分页按钮样式
    4.无刷新排序,可自定义排序栏,排序按钮的样式
    5.自定义无刷新操作后的视图状态[ViewState](1.禁用视图状态 2.只维护数据的视图状态 3.维护全部数据和子控件的视图状态)
    6.简化事件处理,排序和分页只需一个事件

    下载地址:https://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);
            }
    

      

     1         <cc1:TwfGridView ID="TwfGridView1" runat="server" 
     2             onpagesorting="TwfGridView1_PageSorting" AjaxViewState="False" 
     3             AllowPaging="True" AllowSorting="True" FocusBgColor="" jQuerySupport="True" 
     4             LoadMsg="正在加载数据...">
     5         <EPagerSetting NavButton="PrevNumNext" ClassName="TwfGv_All" NavMessageBarCss="TwfGv_NavMessage"
     6         NumBtnBarCss="TwfGv_NumBtnBar" CurrentNumBtnCss="TwfGv_CurrNumBtn" PrevNextBtnCss="TwfGv_PrevNextBtn"
     7         DisabledPrevNextBtnCss="TwfGv_PrevNextDisable" PagerInfoFormatter="&lt;每页 {RecordCount} 条 共 {TotalCount} 条 当前第 {PageIndex}/{PageCount} 页&gt;" 
     8         GoToBarEnable="True" GotoBtnText="转到" GoToDropdown="DropdownSubmit"
     9         GotoClassName="TwfGv_Goto" GotoTxtCss="TwfGv_Goto_Txt"></EPagerSetting>
    10         <ESortSetting SortAscCss="TwfGv_SortAsc" SortDescCss="TwfGv_SortDesc" SortDefaultCss="TwfGv_SortDef"
    11         AscFormatter="{0}↑" DescFormatter="{0}↓"></ESortSetting>
    12         <PagerSettings FirstPageText="首页" LastPageText="末页" NextPageText="下一页" PreviousPageText="上一页"></PagerSettings>
    13         </cc1:TwfGridView>

    快捷设计时:

    分页排序效果:

    当前焦点行颜色效果:

    下拉页选择效果:

    具体实现原理:

    1.重写DataSource属性 适应不同数据源

     1         /// <summary>
     2         /// 获取或设置数据源 支持 DataTable,DataView,ICollection,ITwfRecordCount,IQueryable 等类型的数据源
     3         /// </summary>
     4         public override object DataSource
     5         {
     6             get
     7             {
     8                 return base.DataSource;
     9             }
    10             set
    11             {
    12                 IListSource dtSource = value as IListSource;
    13                 if (dtSource != null){
    14                     _RecordCount = dtSource.GetList().Count;
    15                 }
    16                 else{
    17                     ITwfRecordCount trcSource = value as ITwfRecordCount;
    18                     if (trcSource != null){
    19                         _RecordCount = trcSource.RecordCount();
    20                     }
    21                     else{
    22                         ICollection cletSource = value as ICollection;
    23                         if (cletSource != null){
    24                             _RecordCount = cletSource.Count;
    25                         }
    26                         else{
    27                             IEnumerable aEnum = value as IEnumerable;
    28                             if (aEnum != null) {
    29                                 IEnumerator aEnumtor = aEnum.GetEnumerator();
    30                                 if (aEnumtor != null)
    31                                 {
    32                                     int iCount = 0;
    33                                     aEnumtor.Reset();
    34                                     while (aEnumtor.MoveNext())iCount++;
    35                                     _RecordCount = iCount;
    36                                 }
    37                             }
    38                         }
    39                     }
    40                 }
    41                 VsRecordCount = _RecordCount;
    42                 base.DataSource = value;
    43             }
    44         }


    2.重写控件呈现函数 呈现的时候传递分页参数

     1 private void RenderHtml(HtmlTextWriter defWriter)
     2         {
     3             if (Page != null)
     4             {
     5                 Page.VerifyRenderingInServerForm(this);
     6                 StringBuilder strBuilder = new StringBuilder(2048);
     7                 StringWriter strWriter = new StringWriter(strBuilder);
     8                 HtmlTextWriter htmlWriter = new HtmlTextWriter(strWriter);
     9                 base.RenderChildren(htmlWriter);
    10                 string strVs="",strEvl="";
    11                 TransferFormState(ref strVs, ref strEvl);
    12                 RspCallBackResult(string.Format("SUCCE{0},{1},{2},{3}~{4},{5},{6}~{8}~{9}~{7}", PageIndex.ToString().PadLeft(4, '0'),
    13                     PageCount.ToString().PadLeft(4, '0'), "0000", "0000",aSort.ColumnIndex.ToString(),
    14                     aSort.SortExpression,aSort.DirectString,strBuilder.ToString(),strVs,strEvl));
    15             }
    16             else{
    17                 base.RenderChildren(defWriter);
    18             }
    19         }


    3.处理ViewState让无刷新之后也能保存视图状态(此处用 IL 实现效率会更高)

     1  private void TransferFormState(ref string rVstate,ref string rEvl)
     2         {
     3             if (_AjaxViewState && isVsSupport)
     4             {
     5                 MethodInfo ptrM = Page.GetType().GetMethod("DecomposeViewStateIntoChunks",
     6                     BindingFlags.Instance | BindingFlags.NonPublic);
     7                 ICollection ivs = ptrM.Invoke(Page, null) as ICollection;
     8                 if ((ivs != null) && (ivs.Count > 0))
     9                 {
    10                     StringBuilder strBuilder = new StringBuilder(1024);
    11                     int num = 0, ivc = ivs.Count - 1;
    12                     foreach (string s in ivs)
    13                     {
    14                         strBuilder.Append(s);
    15                         if (num < ivc) strBuilder.Append("#");
    16                         num++;
    17                     }
    18                     rVstate = strBuilder.ToString();
    19                 }
    20                 if (Page.EnableEventValidation)
    21                 {
    22                     ptrM = Page.ClientScript.GetType().GetMethod("GetEventValidationFieldValue",
    23                         BindingFlags.Instance | BindingFlags.NonPublic);
    24                     rEvl = ((ptrM.Invoke(Page.ClientScript, null) as string) ?? "");
    25                 }
    26             }
    27         }


    4.更友好的设计时支持 让控件更易用

     1     public class TwfGridDesignerActionList : DesignerActionList
     2     {
     3         private TwfGridView twfGridView;
     4         public TwfGridDesignerActionList(IComponent component) : base(component) {
     5             twfGridView = component as TwfGridView;
     6             
     7         }
     8         private void SetProperty(string propertyName, object value)
     9         {
    10             TypeDescriptor.GetProperties(twfGridView)[propertyName].SetValue(twfGridView, value);
    11         }
    12         public override DesignerActionItemCollection GetSortedActionItems()
    13         {
    14             DesignerActionItemCollection nitem = new DesignerActionItemCollection();
    15             nitem.Add(new DesignerActionHeaderItem("扩展分页/排序", "kzfypx"));
    16             nitem.Add(new DesignerActionPropertyItem("AllowPaging", "允许分页", "kzfypx"));
    17             nitem.Add(new DesignerActionPropertyItem("AllowSorting", "允许排序", "kzfypx"));
    18             nitem.Add(new DesignerActionPropertyItem("GotoEnable", "启用'转到'按钮", "kzfypx"));
    19             nitem.Add(new DesignerActionPropertyItem("StateMode", "视图状态", "kzfypx", "Part:部分状态\r\nNone:无状态\r\nAll:完全状态"));
    20             nitem.Add(new DesignerActionMethodItem(this, "About", "关于 TwfGridView ...", "kzfypx",true));
    21             return nitem;
    22         }
    23         [EditorBrowsable(EditorBrowsableState.Never)]
    24         public bool GotoEnable
    25         {
    26             get{
    27                 return this.twfGridView.EPagerSetting.GoToBarEnable;
    28             }
    29             set
    30             {
    31                 TypeDescriptor.GetProperties(twfGridView.EPagerSetting)["GoToBarEnable"].SetValue(twfGridView.EPagerSetting,value);
    32                 AllowPaging = AllowPaging;
    33             }
    34 
    35         }
    36         [EditorBrowsable(EditorBrowsableState.Never)]
    37         public void About()
    38         {
    39             (new FrmAbout()).ShowDialog();
    40         }
    41         [EditorBrowsable(EditorBrowsableState.Never)]
    42         public bool AllowSorting {
    43             get { return this.twfGridView.AllowSorting; }
    44             set { SetProperty("AllowSorting", value); }
    45         }
    46         [EditorBrowsable(EditorBrowsableState.Never)]
    47         public bool AllowPaging
    48         {
    49             get { return this.twfGridView.AllowPaging; }
    50             set { SetProperty("AllowPaging", value); }
    51         }
    52         [EditorBrowsable(EditorBrowsableState.Never)]
    53         public TwfGridViewStateMode StateMode
    54         {
    55             get {
    56                 if (!this.twfGridView.EnableViewState) return TwfGridViewStateMode.None;
    57                 if (!this.twfGridView.AjaxViewState) return TwfGridViewStateMode.Part;
    58                 return TwfGridViewStateMode.All;
    59             }
    60             set {
    61                 switch (value)
    62                 {
    63                     case TwfGridViewStateMode.None:
    64                         SetProperty("EnableViewState", false);
    65                         SetProperty("AjaxViewState", false);
    66                         break;
    67                     case TwfGridViewStateMode.Part:
    68                         SetProperty("EnableViewState", true);
    69                         SetProperty("AjaxViewState", false);
    70                         break;
    71                     case TwfGridViewStateMode.All:
    72                         SetProperty("EnableViewState", true);
    73                         SetProperty("AjaxViewState", true);
    74                         break;
    75                     default:
    76                         throw new Exception("error param");
    77                         
    78                 }
    79             }
    80         }
    81     }
  • 相关阅读:
    量子纠错码——Stabilizer codes
    量子计算机编程(三)——量子应用
    量子计算机编程(二)——QPU基础函数
    量子计算机编程(一)——QPU编程
    量子搜索算法 Grover search
    因数分解算法、周期查找算法(简化)
    量子傅里叶变换
    简单的量子算法(二):Simon's Algorithm
    简单的量子算法(一):Hadamard 变换、Parity Problem
    Web Scraper——轻量数据爬取利器
  • 原文地址:https://www.cnblogs.com/dint/p/3833850.html
Copyright © 2011-2022 走看看