.Net中DataGrid多层表头(WinFrom和WebForm)

 

1.  WinForm:
首先需要编写一个类来表示自画的表头,这个类将记录表头的显示文本、图标和属于它管辖的列的信息。

using  System;
using  System.Collections;
using  System.Drawing;

namespace  example
{
 
///  
 
///   表头类
 
///  
  public   class  TopHeaderColumn
 {
   
public  TopHeaderColumn()
   {
     columnCollection
= new  ArrayList();
   }
   
// 用于记录表头管辖的各列的信息
    private  ArrayList columnCollection;
   
public  ArrayList ColumnCollection
   {
     
get
     {
       
return  columnCollection;
     }
     
set
     {
       columnCollection
= value;
     }
   }
   
// 表头的显示文本
    private   string  caption;
   
public   string  Caption
   {
     
get
     {
       
return  caption;
     }
     
set
     {
       caption
= 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做一点修改。编写基于DataGrid控件的新控件myData.

  public   class  myDataGrid:DataGrid
 {
   
// 取得水平滚动条的位置
    public  ScrollBar HScrollBar
   {
     
get
     {
       
return  HorizScrollBar;
     }
   }
 }

好了,可以工作了。在工具箱加入加入myDataGrid,新建一个Window应用程序,一个myDataGrid和ImageList,连接SQL数据库NorthWind。当然,还得加入上面的TopHeaderColumn类。

private   void  Bind()
   
{
     SqlConnection con
=new SqlConnection("server=.;uid=sa;pwd=;database=northwind;");
     con.Open();
     SqlDataAdapter sda
=new SqlDataAdapter();
     sda.SelectCommand
=new SqlCommand("select lastname,firstname,Address,city from employees",con);
     DataSet ds
=new DataSet();
     sda.Fill(ds,
"employees");

     dgData.DataSource
=ds;
     dgData.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";
     dgData.TableStyles.Add(dts);

     
//建立自画的表头类并将它们加入集合al
     al=new ArrayList();
     TopHeaderColumn tc1
=new TopHeaderColumn();
     tc1.Caption
="Name";
     tc1.Image
=imageList1.Images[0];
     
//记录它管辖列的index
     tc1.ColumnCollection.Add(0);
     tc1.ColumnCollection.Add(
1);
     tc1.Width
=c1.Width+c2.Width;

     TopHeaderColumn tc2
=new TopHeaderColumn();
     tc2.Caption
="Address";
     tc2.Image
=imageList1.Images[1];
     tc2.ColumnCollection.Add(
2);
     tc2.ColumnCollection.Add(
3);
     tc2.Width
=c3.Width+c4.Width;

     al.Add(tc1);
     al.Add(tc2);
     dgData.Paint
+=new PaintEventHandler(dgData_Paint);
   }


   
private   void  dgData_Paint( object  sender,System.Windows.Forms.PaintEventArgs e)
   
{
     
int x=0;
     
//计算出第一个表头的左边距
     int left=dgData.TableStyles[0].RowHeaderWidth-dgData.HScrollBar.Value;
     
//遍利表头集合al,画出表头
     foreach(object o in al)
     
{
       
//计算出表头文字的左边距
       x=left+(((TopHeaderColumn)o).Width-Convert.ToInt32(e.Graphics.MeasureString(((TopHeaderColumn)o).Caption,dgData.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,dgData.CaptionFont,
new SolidBrush(dgData.CaptionForeColor),x,0);
       
if(x>0)
         e.Graphics.DrawLine(
new Pen(Color.Black,2),left-1,0,left-1,dgData.Height);
       
//计算下一个表头的左边距
       left+=((TopHeaderColumn)o).Width;
     }

     
if(x        e.Graphics.DrawLine(new Pen(Color.Black,2),left-1,0,left-1,dgData.Height);
   }


   
private   void  abc( object  sender,EventArgs e)
   
{
     
//设置表头的宽度
     foreach(object o in al)
     
{
       ((TopHeaderColumn)o).Width
=0;
       
foreach(int i in ((TopHeaderColumn)o).ColumnCollection)
       
{
         ((TopHeaderColumn)o).Width
+=dgData.TableStyles[0].GridColumnStyles[i].Width;
       }

     }

   }

好了,完成,运行下试试。上面的代码实现了两层表头,至于三层表头也同理。其中:sda.Fill(ds,"employees");如果写成sda.Fill(ds);的话,.net会提示你无法创建employees的子列表。

2.  WebFrom:
WebForm下就更简单了。实际上Asp.Net下的DataGrid只不过是一个HtmlTable,只不过在HtmlTable的基础上添加了很多属性、方法,纳入ViewState机制,来生成、控制它;有了这一点认识,事情就很好办了:适用有模版列。
DataGrid的ItemCreated事件中处理:

 

if (e.Item.ItemType == ListItemType.Header)
            {
                TableCellCollection tcl
= e.Item.Cells;
                tcl.Clear();
                tcl.Add(
new  TableHeaderCell());
                tcl[
0 ].RowSpan = 2 ;
                tcl[
0 ].Text = " No. " ;

                tcl.Add(
new  TableHeaderCell());
                tcl[
1 ].RowSpan = 2 ;
                tcl[
1 ].Text = " <input id='chkSelAll' type='checkbox' name='chkSelAll' οnclick='javascript:CheckAll(Form1,this.checked);'/> " ;

                tcl.Add(
new  TableHeaderCell());
                tcl[
2 ].RowSpan = 2 ;
                tcl[
2 ].Text = " 修改 " ;

                tcl.Add(
new  TableHeaderCell());
                tcl[
3 ].RowSpan = 2 ;
                tcl[
3 ].Text = " 物业项目 " ;

                tcl.Add(
new  TableHeaderCell());
                tcl[
4 ].RowSpan = 2 ;
                tcl[
4 ].Text = " 对应帐套 " ;

                tcl.Add(
new  TableHeaderCell());
                tcl[
5 ].RowSpan = 2 ;
                tcl[
5 ].Text = " 收费项目 " ;

                tcl.Add(
new  TableHeaderCell());
                tcl[
6 ].ColumnSpan = 2 ;
                tcl[
6 ].Text = " 本期收入</td><td colspan=2>预收</td></tr><tr style='color:Black;background-color:#BFBFBF;font-size:9pt;font-weight:bold;'><td>对应会计科目</td><td>对应税金科目</td><td>对应会计科目</td><td>对应税金科目 " ;
            }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值