DataGrid使用技巧(二)
点击次数:15 次 发布日期:2008-11-26 11:12:25 作者:源代码网
|
源代码网推荐 源代码网推荐 ------------如何实现多行表头 源代码网推荐 源代码网推荐 有时候听有些朋友抱怨.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(); 源代码网推荐 } 源代码网推荐 源代码网推荐 上面的代码实现了两层表头,至于三层表头也同理。 源代码网推荐 源代码网推荐 关于如何实现DataGrid多层表头,许多网友都提到,目前好像没有一种特别好的方便的方法。如果那位网友发现了更好的方法,请给我留一条短训告知,谢谢。 做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。 源代码网推荐 源代码网供稿. |
