如何实现多层表头的效果!

hamadou 2005-01-22 05:43:09
如果想在datagrid中实现如下效果:
商品名称 | 价格(RMB) | 购买数量
| | 计划 | 实际
---------------------------------------
保险杠 | 700 | 10 | 9
---------------------------------------
轮胎 | 380 | 20 | 19
---------------------------------------
小 计(小于1000元)(个)| 30 | 28

该如何实现呢,谢谢!

...全文
462 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
landlordh 2005-01-24
  • 打赏
  • 举报
回复
有时候听有些朋友抱怨.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[i].Width;
}
}
}


private void dataGrid1_Scroll(object sender, System.EventArgs e)
{
this.dataGrid1.Refresh();
}

上面的代码实现了两层表头,至于三层表头也同理。
loveme4180 2005-01-24
  • 打赏
  • 举报
回复
up
leeyeefeng2004 2005-01-24
  • 打赏
  • 举报
回复
up、
coldco519 2005-01-24
  • 打赏
  • 举报
回复
在vs.net2003水晶报表的注册码希望大家能给一个,急用
非常谢谢
hamadou 2005-01-24
  • 打赏
  • 举报
回复
to:landlordh(software
是WINFORM,那该如何重写datagrid呢?或者写一个datagridtablestyle类呢?谢谢!
bbswqt 2005-01-24
  • 打赏
  • 举报
回复
如果需要重写DATAGIRD控件的话,还不如直接用DEV for .NET控件呢
landlordh 2005-01-24
  • 打赏
  • 举报
回复
楼主说的不是WEBFORM吧,而是WINFORM

这样需要重写DATAGIRD控件
exing 2005-01-24
  • 打赏
  • 举报
回复
用repeater可以轻松实现
hamadou 2005-01-24
  • 打赏
  • 举报
回复
有vb.net的代码吗?
Qqwwee_Com 2005-01-23
  • 打赏
  • 举报
回复
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'在此处放置初始化页的用户代码
Dim a As New ArrayList
Me.DataGrid1.DataSource = a
Me.DataGrid1.DataBind()
End Sub


Dim Inited As Boolean
Private Sub DataGrid1_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid1.ItemCreated
If Not Inited Then
If e.Item.ItemType = ListItemType.Pager Then
e.Item.Controls.Clear()
'Dim Tr As New TableRow
Dim Td As New TableCell
Td.ColumnSpan = 1
Td.Text = "表1"
e.Item.Controls.Add(Td)
Td = New TableCell
Td.ColumnSpan = 3
Td.Text = "表3"
e.Item.Controls.Add(Td)
End If
End If
End Sub
Qqwwee_Com 2005-01-23
  • 打赏
  • 举报
回复
<asp:DataGrid id="DataGrid1" style="Z-INDEX: 101; LEFT: 240px; POSITION: absolute; TOP: 118px"
runat="server" Width="378px" AutoGenerateColumns="False" AllowPaging="True" >
<Columns>
<asp:BoundColumn DataField="a" HeaderText="a"></asp:BoundColumn>
<asp:BoundColumn DataField="b" HeaderText="b"></asp:BoundColumn>
<asp:BoundColumn DataField="c" HeaderText="c"></asp:BoundColumn>
<asp:BoundColumn DataField="d" HeaderText="d"></asp:BoundColumn>
</Columns>
<PagerStyle Position="TopAndBottom"></PagerStyle>
</asp:DataGrid>

主要属性就是 <PagerStyle Position="TopAndBottom"></PagerStyle> AllowPaging="True"



wqjch 2005-01-23
  • 打赏
  • 举报
回复
我认为用mshflexgrid控件来显示表头,
然后在程序处理一下把datagrid控件的表头用mshflexgrid覆盖它就可以吧
liulxmooo 2005-01-23
  • 打赏
  • 举报
回复
up
hamadou 2005-01-23
  • 打赏
  • 举报
回复
看过了,方法解决不了问题啊!
高手们帮帮忙啊!谢谢!
LoveCherry 2005-01-22
  • 打赏
  • 举报
回复
http://dotnet.aspx.cc/ShowDetail.aspx?id=0BF1E82C-A30A-4B5B-85B2-8DB339A41D37

16,553

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧