首页 > 开发 > 综合 > 正文

现windows应用程序中用的datagrid具有分页功能

2024-07-21 02:22:41
字体:
来源:转载
供稿:网友

工作需要,要实现windows应用程序中用的datagrid具有分页功能,不知道ms怎么想的,asp.net的datagrid有这样的功能,为什么不在winform的datagrid里面提供这样的功能,还得让我费这么大劲儿来重写这个控件,真是麻烦。

首先,我们要做一个类来继承系统的datagrid:

using system;

using system.drawing;

using system.collections;

using system.componentmodel;

using system.windows.forms;

using system.data;

 

namespace oilx.pagingdatagrid

{

public class pagingdatagrid : datagrid

{

  // 声明一些必要的全局变量。

private system.componentmodel.container components = null;

 

                      /// <summary>

                      ///                  

/// </summary>

                      private const int markerwith = 14;

 

                      /// <summary>

                      ///

                      /// </summary>

                      private point      _pointtopleft; 

 

                      /// <summary>

                      ///

                      /// </summary>

                      private int _row = 1;

 

                      //

                      private int _rownumberfigure = 0;

                      private bool _zeropadding = false;

 

                      /// <summary>

                      ///

                      /// </summary>

                      private string _rowheadercaption = string.empty;

 

                      /// <summary>

                      ///

                      /// </summary>

                      private int _pagesize = 10;

 

                      /// <summary>

                      ///

                      /// </summary>

                      private int _currentpagecount = 1;

 

                      /// <summary>

                      ///

                      /// </summary>

                      private bool _allowpaging = false;

 

                      /// <summary>

                      ///

                      /// </summary>

                      private int _previouspagecount = -1;

                      /// <summary>

                      ///

                      /// </summary>

                      private datatable _pagedatasource;

 

/// <summary>

///构造函数

/// </summary>

/// <param name="container"></param>

public pagingdatagrid (system.componentmodel.icontainer container)

{

           container.add(this);

           initializecomponent();

           initiarizecontrol();

}

/// <summary>

///构造函数重载

/// </summary>

public fixditemdatagrid()

{

           initializecomponent();

           initiarizecontrol();

                                 

}

// 下面我们需要增加一些用于分页的公共属性

/// <summary>

/// 页面大小,即每页现实的数据条数

/// </summary>

[browsable(true),description("页面大小")]

public int pagesize

{

           get

           {

                      return _pagesize;

           }

           set

           {

                      _pagesize = value;

           }

}

/// <summary>

/// 分页数

/// </summary>

[browsable(true),description("分页数")]

public int pagecount

{

           get

           {

                      if(datasource == null)

                      {

                                  return 0;

                      }

                      if(_pagedatasource == null || _pagedatasource.rows.count <= 0)

                      {

                                  return 0;

                      }

                      int i = _pagedatasource.rows.count%pagesize==0?0:1;

                      return _pagedatasource.rows.count/pagesize+i;

           }

}

/// <summary>

/// 当前页数

/// </summary>

[browsable(true),description("当前页数")]

public int currentpagecount

{

           get

           {

                      if(_currentpagecount < 0)

                      {

                                  return 1;

                      }

                      if(_currentpagecount >= pagecount)

                      {

                                  return pagecount;

                      }

                      return _currentpagecount;

           }

           set

           {

                      if(value >=pagecount)

                      {

                                  _currentpagecount =  pagecount;

                      }

                      _currentpagecount = value;

           }

}

/// <summary>

///是否允许分页

/// </summary>

[browsable(true),description("是否允许分页")]

public bool allowpaging

{

           get

           {

                      return _allowpaging;

           }

           set

           {

                      _allowpaging = value;

           }

}

/// <summary>

///行标题

/// </summary>

[browsable(true),description("行标题")]

public string rowheadercaption

{

           get

           {

                      return _rowheadercaption;

           }

           set

           {

                      _rowheadercaption = value;

           }

}

 

// 基本工作都作完了,下面开始我们分页的重点,go!

// 我们需要重写系统一个方法,那就是:

/// <summary>

/// 该方法在数据源被修改的时候激活。

/// </summary>

/// <param name="e"></param>

protected override void ondatasourcechanged(system.eventargs e)

{

           base.ondatasourcechanged(e);

           // 如果数据源为空那么就返回。

           if( this.datasource == null )

           {

                      return;

           }

           // 下面判断数据源的类型,一般情况下,datagrid数据源形式为3种,1,dataset,2,datatable,3,dataview。

           // 在这里我们要做的是把数据源的数据保存到另外一个变量里面,这样当我们在作分页

           //的时候,需要修改数据源时,可以把这个变量当作原始的数据源来进行判断。

           if(this.datasource is dataset)

           {

                      if( ((dataset)datasource).tables.count > 0)

                      {

                                  this.datasource = ((dataset)datasource).tables[0];

                      }

                      else

                      {

                                  return;

                      }

           }

           if(_pagedatasource == null)

           {

                      if(datasource is dataset)

                      {

                                                        if(((dataset)datasource).tables[0].rows.count <=0)

           {

                      return;

           }

           _pagedatasource = ((dataset)datasource).tables[0].clone();

           for(int i = 0;i<((dataset)datasource).tables[0].rows.count;i++)

           {

                      datarow drrow = _pagedatasource.newrow();

                      drrow.itemarray = ((dataset)datasource).tables[0].rows[i].itemarray;

                      _pagedatasource.rows.add(drrow);

           }

}

           else if(datasource is datatable)

           {

                      if(((datatable)datasource).rows.count <= 0)

                      {

                                  return;

                      }

                      _pagedatasource = ((datatable)datasource).clone();

           for(int i = 0;i<((datatable)datasource).rows.count;i++)

           {

                      datarow drrow = _pagedatasource.newrow();

                      drrow.itemarray = ((datatable)datasource).rows[i].itemarray;

                      _pagedatasource.rows.add(drrow);

           }

}

else if(datasource is dataview)

{                    

if( ((dataview)datasource).table.rows.count <= 0)

           {

                      return;

           }

           _pagedatasource = ((dataview)datasource).table.clone();

           for(int i = 0;i<((dataview)datasource).table.rows.count;i++)

           {

                      datarow drrow = _pagedatasource.newrow();

                      drrow.itemarray = ((dataview)datasource).table.rows[i].itemarray;

                      _pagedatasource.rows.add(drrow);

           }

}

}

_pointtopleft = new point(this.getcellbounds(0,0).x + 4, this.getcellbounds(0,0).y + 4);

}

// 上面的所作的只是把原数据源数据导入到_pagedatasource这个datatable里面,在这里有

//人可能要问为什么不用 _pagedatasource = (datatable)this.datasource;

// 而使用

//datarow drrow = _pagedatasource.newrow();

//drrow.itemarray = ((dataview)datasource).table.rows[i].itemarray;

//_pagedatasource.rows.add(drrow);

//这是因为datatable是引用类型,如果直接付值的话,那么当原数据源的数据被修改时,——//_pagedatasource也会被修改。

//好了,临时数据已经处理完了,那么真正的分页处理开始,大家都知道,.net控件要显示在窗体//上,那么需要我们把它的实体画上去,那么ms.net在所有控件都提供了下面这样的方法,可以//让我们把控件按照我们修改后的形式表现出来:

/// <summary>

///

/// </summary>

/// <param name="e"></param>

protected override void onpaint(system.windows.forms.painteventargs e)

{

base.onpaint(e);

           if( this.datasource == null )

           {

                      return;

           }

           if(datasource != null && datasource is dataset)

           {

                      return;

           }

           // 在这里我们开始对分页进行进行处理          

           if(allowpaging)

           {

                      if(_pagedatasource != null)

                      {

                                  if(_previouspagecount != currentpagecount)

                                  {

                                             // 判断当前是第几页

                                             int i = currentpagecount*pagesize-pagesize;

                                             if(i<0)

                                             {

                                                        i = 0;

                                             }

//下面判断是否为最后一页

                                             if(i <= _pagedatasource.rows.count)

                                             {

                                                        datatable dtpage = _pagedatasource.clone();

                                                        int icount = 0;

           根据pagesize来生成一个datatable,重新进行数据源绑定。

           for(;i<_pagedatasource.rows.count;i++)

           {

                                                                             

                      datarow drrow = dtpage.newrow();

                                                                                          drrow.itemarray= _pagedatasource.rows[i].itemarray;

                                                                                          dtpage.rows.add(drrow);

                      icount ++;

                                                                                          if(icount>=pagesize)

           {

                      break;

           }

           }

           // 绑定新的数据源

           this.datasource = dtpage;

}

_previouspagecount = currentpagecount;

}

}

}

           // rowheaders如果为true,那么我们要给rowheader上面标上序号和标题

           if(this.rowheadersvisible)

           {

                      datagrid.hittestinfo hti = this.hittest(_pointtopleft);

                      int irowhti = hti.row;

                      if(irowhti < 0)

                      {

                                  irowhti = 0;

                      }

                      int idelta = this.getcellbounds(irowhti, 0).height + 1;

                      int iheight = this.getcellbounds(irowhti, 0).top + 1;

                      // 这个方法里面是显示rowheaders的标题,详见该方法实现

                      showcolumntitles(e);

                      currencymanager cm = (currencymanager) this.bindingcontext[this.datasource, this.datamember];

                      while(iheight < this.height - idelta && irowhti < cm.count)

                      {

                                  string strtext = string.empty;

                                  if(_zeropadding)

                                  {

                                             strtext = string.format("{0}", _row + irowhti).padleft(_rownumberfigure, '0');

                                  }

                                  else

                                  {

                                             strtext = string.format("{0}", _row + irowhti);

                                  }

                                  e.graphics.drawstring(strtext, this.font, new solidbrush(color.black), 20, iheight);

                                  // 下面处理的是在rowheaders上面画一条分割线,为了有阴影的感觉,我画了一条灰色和白色两条,看着还挺像 ^_^

                                  if(!this.captionvisible)

                                  {

                                            showsepalatorline(e, new point(17, 2), new point(17, iheight-2 + this.preferredrowheight),color.gray);

                                             showsepalatorline(e, new point(18, 2), new point(18, iheight-2 + this.preferredrowheight),color.white);

                                  }

                                  else

                                  {

                                             showsepalatorline(e, new point(17, 20), new point(17, iheight-2 + this.preferredrowheight),color.gray);

                                            showsepalatorline(e, new point(18, 20), new point(18, iheight-2 + this.preferredrowheight),color.white);

                                  }

                                  iheight += idelta;

                                  irowhti++;

                      }

                      _row =currentpagecount*pagesize-pagesize+1;

                      if(_row < 0)

                      {

                                  _row =1;

                      }

           }

}

// 画线

private void showsepalatorline(painteventargs e, point ptstart, point ptend,color linecolor)

{

           pen pen = new pen(new solidbrush(linecolor), 1);

           e.graphics.drawline(pen, ptstart, ptend);

}

/// <summary>

/// 显示rowheaders的标题

/// </summary>

/// <param name="e"></param>

/// <param name="source"></param>

private void showcolumntitles(painteventargs e)

{

           string strheader = rowheadercaption;

           int ix     = markerwith + 5;

           int iwith  = this.rowheaderwidth;

           using(stringformat sf = new stringformat())

           {

                      sf.formatflags   = stringformatflags.nowrap;

                      sf.trimming      = stringtrimming.ellipsischaracter;

                      sf.alignment     = stringalignment.near;

                      sf.linealignment = stringalignment.center;

                      rectanglef rect;

                      if(!captionvisible)

                      {

                                  rect = new rectanglef(new pointf(ix, 3), new sizef(iwith, this.preferredrowheight));

                      }

                      else

                      {

                                  rect = new rectanglef(new pointf(ix, 20), new sizef(iwith, this.preferredrowheight));

                      }

                      e.graphics.drawstring(strheader, this.font, new solidbrush(color.black), rect, sf);

           }

}

/// <summary>

/// ?}?e?x?|?c?“?^‚???“®¸?—¯

/// </summary>

/// <param name="e"></param>

protected override void onmousemove(system.windows.forms.mouseeventargs e)

{

           datagrid.hittestinfo hittestinfo = this.hittest(new point(e.x, e.y))          if(hittestinfo.type == datagrid.hittesttype.rowresize)

           {

                      return;

           }

           base.onmousemove(e);

                      }

 

/// <summary> ///

/// </summary>

/// <param name="e"></param>

protected override void onmousedown(system.windows.forms.mouseeventargs e)

{

           datagrid.hittestinfo hittestinfo = this.hittest(new point(e.x, e.y));

           if(hittestinfo.type == datagrid.hittesttype.rowresize)

           {

                      return;

           }

           base.onmousedown(e);

}         

}

} 好了,到这里这个,这个分页的datagrid就算完了。程序实现:datagrid1.currentpagecount ++;datagrid1.invalidate();一定要写datagrid1.invalidate();这个方法,不然datagrid不能刷新,看不到分页效果!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表