打印

[asp.net教程] datagrid使用技巧(二)

datagrid使用技巧(二)

------------如何实现多行表头
   
   有时候听有些朋友抱怨.net的datagrid不是很好用。就我个人的体会,datagrid的功能非常强大,可以使我们随心所欲的完成各种各样的工作,可惜就是实现起来不够简单明了。我对平时经常碰到的一些问题积累了一些解决的方法,现在把它们总结一下供大家参考。
   比较经常碰到的一个问题是:我们希望datagrid的表头是多行的(图1)。我在网上找了很久也找不到解决的方法,后来想到了datagrid的captiontext和captionfont属性。于是我就想能不能在caption的显示区域画出多行表头。下面的示例代码实现了这个想法,结果如图1所示。
   
   
   
   首先需要编写一个类来表示自画的表头,这个类将记录表头的显示文本、图标和属于它管辖的列的信息。
   
   
   //表头类
   public class topheadercolumn
   {
   public topheadercolumn()
   {
   this.columncollection=new arraylist();
   }
   private string caption;
   //表头的显示文本
   public string caption
   {
   get {return caption;}
   set {caption=value;}
   }
   private arraylist columncollection;
   //用来记录属于表头管辖的各列的信息(通过往集合里添加object)
   public arraylist columncollection
   {
   get {return this.columncollection;}
   set {this.columncollection=value;}
   }
   private int width;
   //表头的宽度
   public int width
   {
   get {return width;}
   set {width=value;}
   }
   private image image=null;
   //表头的图标
   public image image
   {
   get {return image;}
   set {image=value;}
   }
   
   }
   另外,因为以后的代码需要datagrid水平滚动条的位置,而datagrid无法取得水平滚动条的位置,所以需要对datagrid做一点修改。
   public class mydatagrid:datagrid
   {
   
   public scrollbar hscrollbar
   {
   get {return this.horizscrollbar;}
   }
   }
   
   好了,可以工作了。新建一个window应用程序,加入一个mydatagrid、sqlconnection和imagelist,连接sql数据库northwind。当然,还得加入上面的代码

   
   namespace windowsapplication1
   {
   public class form1 : system.windows.forms.form
   {
   private system.data.sqlclient.sqlconnection sqlconnection1;
   private mydatagrid datagrid1;
   private arraylist al;
   private system.windows.forms.imagelist imagelist1;
   \\在initializecomponent()里加入这一句:this.datagrid1 = new mydatagrid(),并根据你的需要设置其他的datagrid属性。注意,captionvisible必须设为true,captiontext=""。
   private void form1_load(object sender, system.eventargs e)
   {
   sqldataadapter da=new sqldataadapter("select lastname, firstname, address,city from employees",this.sqlconnection1);
   dataset ds=new dataset();
   da.fill(ds,"employees");
   this.datagrid1.datasource=ds;
   this.datagrid1.datamember="employees";
   
   //设置datagrid的各列
   datagridtextboxcolumn c1=new datagridtextboxcolumn();
   datagridtextboxcolumn c2=new datagridtextboxcolumn();
   datagridtextboxcolumn c3=new datagridtextboxcolumn();
   datagridtextboxcolumn c4=new datagridtextboxcolumn();
   c1.mappingname="lastname";
   c2.mappingname="firstname";
   c3.mappingname="address";
   c4.mappingname="city";
   c1.headertext="lastname";
   c2.headertext="firstname";
   c3.headertext="address";
   c4.headertext="city";
   c1.widthchanged+=new eventhandler(this.abc);//列的宽变动时调整表头宽度
   c2.widthchanged+=new eventhandler(this.abc);
   c3.widthchanged+=new eventhandler(this.abc);
   c4.widthchanged+=new eventhandler(this.abc);
   
   datagridtablestyle dts=new datagridtablestyle();
   dts.gridcolumnstyles.add(c1);
   dts.gridcolumnstyles.add(c2);
   dts.gridcolumnstyles.add(c3);
   dts.gridcolumnstyles.add(c4);
   
   dts.mappingname="employees"; this.datagrid1.tablestyles.add(dts);
   
   //建立自画的表头类并将它们加入集合al
   al=new arraylist();
   topheadercolumn tc1=new topheadercolumn();
   tc1.caption="name";
   tc1.image=this.imagelist1.images[0];
   tc1.columncollection.add(0);//记录它管辖的列的index
   tc1.columncollection.add(1);
   tc1.width=c1.width+c2.width;
   
   topheadercolumn tc2=new topheadercolumn();
   tc2.caption="address";
   tc2.columncollection.add(2);
   tc2.columncollection.add(3);
   tc2.width=c3.width+c4.width;
   
   al.add(tc1);
   al.add(tc2);
   this.datagrid1.paint += new system.windows.forms.painteventhandler(this.datagrid1_paint);
   }
   
   private void datagrid1_paint(object sender, system.windows.forms. painteventargs e)
   {
   int x=0;
   //计算出第一个表头的左边距
   int left=this.datagrid1.tablestyles[0].rowheaderwidth-this.datagrid1.hscrollbar.value;
   //遍历表头集合al,画出表头
   foreach (object o in this.al)
   {
   //计算出表头文字(文字居中)的左边距
   x=left+(((topheadercolumn)o).width-convert.toint32(e.graphics. measurestring (((topheadercolumn)o).caption, this.datagrid1.captionfont). width))/2;
   //完成表头绘制
   if (((topheadercolumn)o).image!=null)
   e.graphics.drawimage(((topheadercolumn)o).image,x-imagelist1.images[0].size.width,0);
   
   e.graphics.drawstring(((topheadercolumn)o).caption,this.datagrid1. captionfont,new solidbrush(this.datagrid1.captionforecolor),x,0);
   if (x>0)
   e.graphics.drawline(new pen(color.black,2),left-1,0,left-1,this.datagrid1.height);
   //计算出下一个表头的左边距
   left+=((topheadercolumn)o).width;
   }
   if (x<this.datagrid1.width)
   e.graphics.drawline(new pen(color.black,2),left-1,0,left-1,this.datagrid1.height);
   }
   
   private void abc(object sender,eventargs e)
   {
   //设置表头的宽度
   foreach (object o in this.al)
   {
   ((topheadercolumn)o).width=0;
   foreach (int i in ((topheadercolumn)o).columncollection)
   { ((topheadercolumn)o).width+=this.datagrid1.tablestyles[0].gridcolumnstyles.width;
   }
   }
   }
   
   
   private void datagrid1_scroll(object sender, system.eventargs e)
   {
   this.datagrid1.refresh();
   }
   
   上面的代码实现了两层表头,至于三层表头也同理。
   
   关于如何实现datagrid多层表头,许多网友都提到,目前好像没有一种特别好的方便的方法。如果那位网友发现了更好的方法,请给我留一条短训告知,谢谢。

TOP

返回顶部
AYBlue

Processed in 0.045315 second(s), 7 queries.

当前时区 GMT+8, 现在时间是 2009-1-10 10:53 京ICP备06054220号

清除 Cookies - 联系我们 - 163K.com - Archiver - WAP