WinForm DataGrid多列标题

本文介绍了一种扩展的DataGrid控件DataGridEx,用于在WinForm应用中实现跨列合并的功能,使得DataGrid能够更好地展示分组或层级数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    前些日子,一个程序需要在WinForm中的DataGrid上设置两列标题,为了方便(其实也是懒了一下),在网上找了一个
扩展DataGrid的用户控件,用了之后觉得很好用,现拿出来给大家共享:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace FZL
{
	public partial class DataGridViewEx : DataGridView
	{
		public DataGridViewEx()
		{
			InitializeComponent();
		}
		protected override void OnPaint(PaintEventArgs pe)
		{
			//   TODO:   在此处添加自定义绘制代码 

			//   调用基类   OnPaint 
			base.OnPaint(pe);
		}
		private struct SpanInfo     //表头信息 
		{
			public SpanInfo(string Text, int Position, int Left, int Right)
			{
				this.Text = Text;
				this.Position = Position;
				this.Left = Left;
				this.Right = Right;
			}

			public string Text;           //列主标题 
			public int Position;         //位置,1:左,2中,3右 
			public int Left;                 //对应左行 
			public int Right;               //对应右行 
		}

		private Dictionary<int, SpanInfo> SpanRows = new Dictionary<int, SpanInfo>();//需要2维表头的列 
		public void AddSpanHeader(int ColIndex, int ColCount, string Text)
		{
			//if   (ColCount   <   2) 
			//        throw   new   Exception("行宽应大于等于2,合并1列无意义。"); 

			//检查范围 
			for (int i = 0; i < ColCount; i++)
			{
				if (SpanRows.ContainsKey(ColIndex + i))
					throw new Exception("单元格范围重叠!");
			}

			//将这些列加入列表 
			int Right = ColIndex + ColCount - 1;         //同一大标题下的最后一列的索引 
			SpanRows[ColIndex] = new SpanInfo(Text, 1, ColIndex, Right);         //添加标题下的最左列 
			SpanRows[Right] = new SpanInfo(Text, 3, ColIndex, Right);       //添加该标题下的最右列 
			for (int i = ColIndex + 1; i < Right; i++)     //中间的列 
			{
				SpanRows[i] = new SpanInfo(Text, 2, ColIndex, Right);
			}
		}

		public void ClearSpanInfo()
		{
			SpanRows.Clear();
			//ReDrawHead(); 
		}

		private void DataGridViewEx_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
		{
			if (e.RowIndex == -1)
			{
				if (SpanRows.ContainsKey(e.ColumnIndex))     //被合并的列 
				{
					//画边框 
					Graphics g = e.Graphics;
					e.Paint(e.CellBounds, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);

					int left = e.CellBounds.Left, top = e.CellBounds.Top + 2,
							right = e.CellBounds.Right, bottom = e.CellBounds.Bottom;

					switch (SpanRows[e.ColumnIndex].Position)
					{
						case 1:
							left += 2;
							break;
						case 2:
							break;
						case 3:
							right -= 2;
							break;
					}

					//画上半部分底色 
					g.FillRectangle(new SolidBrush(e.CellStyle.BackColor), left, top,
							right - left, (bottom - top) / 2);

					//画中线 
					g.DrawLine(new Pen(this.GridColor), left, (top + bottom) / 2,
							right, (top + bottom) / 2);

					//写小标题 
					StringFormat sf = new StringFormat();
					sf.Alignment = StringAlignment.Center;
					sf.LineAlignment = StringAlignment.Center;

                    
                    g.DrawString(e.Value + "", e.CellStyle.Font, Brushes.Black,
					new Rectangle(left, (top + bottom) / 2, right - left, (bottom - top) / 2), sf);

					//写大标题 
					//if   (this.SpanRows[e.ColumnIndex].Position==3) 

					left = this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Left, true).Left - 2;

					if (left < 0) left = this.GetCellDisplayRectangle(-1, -1, true).Width;
					right = this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Right, true).Right - 2;
					if (right < 0) right = this.Width;

                    g.DrawString(SpanRows[e.ColumnIndex].Text, e.CellStyle.Font, Brushes.Black,
							new Rectangle(left, top, right - left, (bottom - top) / 2), sf);

					e.Handled = true;
				}
			}
		}
		private void DataGridViewEx_Scroll(object sender, ScrollEventArgs e)
		{
			if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)//   &&   e.Type   ==   ScrollEventType.EndScroll) 
			{
				timer1.Enabled = false; timer1.Enabled = true;
			}
		}

		//刷新显示表头 
		public void ReDrawHead()
		{
			foreach (int si in SpanRows.Keys)
			{
				this.Invalidate(this.GetCellDisplayRectangle(si, -1, true));
			}
		}

		private void timer1_Tick(object sender, EventArgs e)
		{
			timer1.Enabled = false;
			ReDrawHead();
		}
		///   <summary > 
		///   必需的设计器变量。 
		///   </summary > 
		private System.ComponentModel.IContainer components = null;

		///   <summary > 
		///   清理所有正在使用的资源。 
		///   </summary > 
		///   <param   name="disposing" >如果应释放托管资源,为   true;否则为   false。 </param > 
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region   组件设计器生成的代码

		///   <summary > 
		///   设计器支持所需的方法   -   不要 
		///   使用代码编辑器修改此方法的内容。 
		///   </summary > 
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			this.timer1 = new System.Windows.Forms.Timer(this.components);
			((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
			this.SuspendLayout();
			//   
			//   timer1 
			//   
			this.timer1.Interval = 20;
			this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
			//   
			//   DataGridViewEx1 
			//   
			this.RowTemplate.Height = 23;
			this.ColumnHeadersHeight = 40;
			this.CellPainting += new System.Windows.Forms.DataGridViewCellPaintingEventHandler(this.DataGridViewEx_CellPainting);
			this.Scroll += new System.Windows.Forms.ScrollEventHandler(this.DataGridViewEx_Scroll);
			((System.ComponentModel.ISupportInitialize)(this)).EndInit();
			this.ResumeLayout(false);

		}
		#endregion

		private System.Windows.Forms.Timer timer1;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值