public partial class HeaderUnitView : DataGridView
{ private TreeView[] _columnTreeView; private ArrayList _columnList = new ArrayList(); private int _cellHeight = 17;public int CellHeight
{ get { return _cellHeight; } set { _cellHeight = value; } } private int _columnDeep = 1;private bool HscrollRefresh = false;
/// <summary> /// 水平滚动时是否刷新表头,数据较多时可能会闪烁,不刷新时可能显示错误 /// </summary> [Description("水平滚动时是否刷新表头,数据较多时可能会闪烁,不刷新时可能显示错误")] public bool RefreshAtHscroll { get { return HscrollRefresh; } set { HscrollRefresh = value; } } /// <summary> /// 构造函数 /// </summary> public HeaderUnitView() { InitializeComponent(); this.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing; //设置列高度显示模式 }[Description("设置或获得合并表头树的深度")]
public int ColumnDeep { get { if (this.Columns.Count == 0) _columnDeep = 1;this.ColumnHeadersHeight = _cellHeight * _columnDeep;
return _columnDeep; }set
{ if (value < 1) _columnDeep = 1; else _columnDeep = value; this.ColumnHeadersHeight = _cellHeight * _columnDeep; } } [Description("添加合并式单元格绘制的所需要的节点对象")] public TreeView[] ColumnTreeView { get { return _columnTreeView; } set { if (_columnTreeView != null) { for (int i = 0; i <= _columnTreeView.Length - 1; i++) _columnTreeView[i].Dispose(); } _columnTreeView = value; } }[Description("设置添加的字段树的相关属性")]
public TreeView ColumnTreeViewNode { get { return _columnTreeView[0]; } }public ArrayList NadirColumnList
{ get { if (_columnTreeView == null) return null;if (_columnTreeView[0] == null)
return null;if (_columnTreeView[0].Nodes == null)
return null;if (_columnTreeView[0].Nodes.Count == 0)
return null;_columnList.Clear();
GetNadirColumnNodes(_columnList, _columnTreeView[0].Nodes[0], false); return _columnList; } } ///<summary> ///绘制合并表头 ///</summary> ///<param name="node">合并表头节点</param> ///<param name="e">绘图参数集</param> ///<param name="level">结点深度</param> ///<remarks></remarks> public void PaintUnitHeader( TreeNode node, System.Windows.Forms.DataGridViewCellPaintingEventArgs e, int level) { //根节点时退出递归调用 if (level == 0) return;RectangleF uhRectangle;
int uhWidth; SolidBrush gridBrush = new SolidBrush(this.GridColor); SolidBrush backColorBrush = new SolidBrush(e.CellStyle.BackColor); Pen gridLinePen = new Pen(gridBrush); StringFormat textFormat = new StringFormat(); textFormat.Alignment = StringAlignment.Center;uhWidth = GetUnitHeaderWidth(node);
if( node.Nodes.Count == 0)
{ uhRectangle = new Rectangle(e.CellBounds.Left, e.CellBounds.Top + node.Level * _cellHeight, uhWidth - 1, _cellHeight * (_columnDeep - node.Level) - 1); } else { uhRectangle = new Rectangle( e.CellBounds.Left, e.CellBounds.Top + node.Level * _cellHeight, uhWidth - 1, _cellHeight - 1); }//画矩形
e.Graphics.FillRectangle(backColorBrush, uhRectangle); //划底线 e.Graphics.DrawLine(gridLinePen , uhRectangle.Left , uhRectangle.Bottom , uhRectangle.Right , uhRectangle.Bottom); //划右端线 e.Graphics.DrawLine(gridLinePen , uhRectangle.Right , uhRectangle.Top , uhRectangle.Right , uhRectangle.Bottom); 写字段文本e.Graphics.DrawString(node.Text, this.Font
, new SolidBrush(e.CellStyle.ForeColor) , uhRectangle.Left + uhRectangle.Width / 2 - e.Graphics.MeasureString(node.Text, this.Font).Width / 2 - 1 , uhRectangle.Top + uhRectangle.Height / 2 - e.Graphics.MeasureString(node.Text, this.Font).Height / 2); //Image img = new Bitmap((int)uhRectangle.Width, (int)uhRectangle.Height); //Graphics g = Graphics.FromImage(img); //g.FillRectangle(backColorBrush, uhRectangle); //g.DrawLine(gridLinePen // , uhRectangle.Left // , uhRectangle.Bottom // , uhRectangle.Right // , uhRectangle.Bottom); //g.DrawLine(gridLinePen // , uhRectangle.Right // , uhRectangle.Top // , uhRectangle.Right // , uhRectangle.Bottom); //g.DrawString(node.Text, e.CellStyle.Font, new SolidBrush(e.CellStyle.ForeColor), uhRectangle.Left + uhRectangle.Width / 2 - g.MeasureString(node.Text, this.Font).Width / 2 - 1, uhRectangle.Top + // uhRectangle.Height / 2 - g.MeasureString(node.Text, this.Font).Height / 2, textFormat); //this.Rows[e.RowIndex].Cells[e.ColumnIndex].ValueType = typeof(Image); //this.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = img; 递归调用() if (node.PrevNode == null) if (node.Parent != null) PaintUnitHeader(node.Parent, e, level - 1); }/// <summary>
/// 获得合并标题字段的宽度 /// </summary> /// <param name="node">字段节点</param> /// <returns>字段宽度</returns> /// <remarks></remarks> private int GetUnitHeaderWidth(TreeNode node) { //获得非最底层字段的宽度int uhWidth = 0;
//获得最底层字段的宽度 if (node.Nodes == null) return this.Columns[GetColumnListNodeIndex(node)].Width;if (node.Nodes.Count == 0)
return this.Columns[GetColumnListNodeIndex(node)].Width;for (int i = 0; i <= node.Nodes.Count - 1; i++)
{ uhWidth = uhWidth + GetUnitHeaderWidth(node.Nodes[i]); } return uhWidth; } /// <summary> /// 获得底层字段索引 /// </summary> ///' <param name="node">底层字段节点</param> /// <returns>索引</returns> /// <remarks></remarks> private int GetColumnListNodeIndex(TreeNode node) { for (int i = 0; i <= _columnList.Count - 1; i++) { if (((TreeNode)_columnList[i]).Equals(node)) return i; } return -1; } /// <summary> /// 获得底层字段集合 /// </summary> /// <param name="alList">底层字段集合</param> /// <param name="node">字段节点</param> /// <param name="checked">向上搜索与否</param> /// <remarks></remarks> private void GetNadirColumnNodes( ArrayList alList, TreeNode node, Boolean isChecked) { if (isChecked == false) { if (node.FirstNode == null) { alList.Add(node); if (node.NextNode != null) { GetNadirColumnNodes(alList, node.NextNode, false); return; } if (node.Parent != null) { GetNadirColumnNodes(alList, node.Parent, true); return; } } else { if (node.FirstNode != null) { GetNadirColumnNodes(alList, node.FirstNode, false); return; } } } else { if (node.FirstNode == null) { return; } else { if (node.NextNode != null) { GetNadirColumnNodes(alList, node.NextNode, false); return; }if (node.Parent != null)
{ GetNadirColumnNodes(alList, node.Parent, true); return; } } } } /// <summary> /// 滚动 /// </summary> /// <param name="e"></param> protected override void OnScroll(ScrollEventArgs e) { bool scrollDirection = (e.ScrollOrientation == ScrollOrientation.HorizontalScroll); base.OnScroll(e); if (RefreshAtHscroll && scrollDirection) this.Refresh(); } /// <summary> /// 列宽度改变的重写 /// </summary> /// <param name="e"></param> protected override void OnColumnWidthChanged(DataGridViewColumnEventArgs e) { Graphics g=Graphics.FromHwnd(this.Handle); float uwh=g.MeasureString(e.Column.HeaderText, this.Font).Width; if (uwh >= e.Column.Width) { e.Column.Width = Convert.ToInt16(uwh);} base.OnColumnWidthChanged(e); } /// <summary> /// 单元格绘制(重写) /// </summary> /// <param name="e"></param> /// <remarks></remarks> protected override void OnCellPainting(System.Windows.Forms.DataGridViewCellPaintingEventArgs e) { try { //行标题不重写 if (e.ColumnIndex < 0) { base.OnCellPainting(e); return; }if (_columnDeep == 1)
{ base.OnCellPainting(e); return; }//绘制表头
if (e.RowIndex == -1) { if (e.ColumnIndex >= NadirColumnList.Count) { e.Handled = true; return; } PaintUnitHeader((TreeNode)NadirColumnList[e.ColumnIndex] , e , _columnDeep); e.Handled = true; } } catch { } } }
网格:
public partial class RowUnitView : DataGridView
{ public RowUnitView() { InitializeComponent(); this.MultiSelect = true; this.SelectionMode = DataGridViewSelectionMode.FullRowSelect; this.AllowUserToAddRows = false; this.RowHeadersVisible = false; this.ReadOnly = true; } private int i = 1; private int count2 = 1; private int flag; string selectedValue; protected override void OnPaint(PaintEventArgs pe) { // TODO: 在此处添加自定义绘制代码// 调用基类 OnPaint
base.OnPaint(pe); } protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e) { try { DrawCell(e); base.OnCellPainting(e); } catch { } } /// <summary> /// 画单元格 /// </summary> /// <param name="e"></param> private void DrawCell(DataGridViewCellPaintingEventArgs e) { Brush gridBrush = new SolidBrush(this.GridColor); SolidBrush backBrush = new SolidBrush(e.CellStyle.BackColor); SolidBrush fontBrush = new SolidBrush(e.CellStyle.ForeColor); int cellheight; int fontheight; int cellwidth; int fontwidth; int countU = 0; int countD = 0; int count = 0; int totalheight = 0; int heightU = 0; int heightD = 0; // 对第1,2列相同单元格进行合并 if ((e.ColumnIndex == 0 || e.ColumnIndex == 1) && e.RowIndex != -1) { // cellheight = e.CellBounds.Height; // fontheight = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Height; // cellwidth = e.CellBounds.Width; // fontwidth = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Width; // Pen gridLinePen = new Pen(gridBrush); // string curValue = e.Value == null ? "" : e.Value.ToString().Trim(); // string curSelected = this.CurrentRow.Cells[0].Value == null ? "" : this.CurrentRow.Cells[0].Value.ToString().Trim(); // if (!string.IsNullOrEmpty(curValue)) // { // for (int i = e.RowIndex; i < this.Rows.Count; i++) // { // if (this.Rows[i].Cells[0].Value.ToString().Equals(curValue)) // { // this.Rows[i].Cells[0].Selected = this.Rows[e.RowIndex].Selected; // this.Rows[i].Selected = this.Rows[e.RowIndex].Selected; // countD++; // heightD += this.Rows[i].Height; // } // else // { // break; // } // } // for (int i = e.RowIndex; i >= 0; i--) // { // if (this.Rows[i].Cells[0].Value.ToString().Equals(curValue)) // { // this.Rows[i].Cells[0].Selected = this.Rows[e.RowIndex].Selected; // this.Rows[i].Selected = this.Rows[e.RowIndex].Selected; // heightU += this.Rows[i].Height; // countU++; // } // else // { // break; // } // } // heightU = heightU - e.CellBounds.Height; // totalheight = heightU + heightD; // count = countD + countU -1; // if (count < 2) { return; } // } // if (this.Rows[e.RowIndex].Selected) // { // backBrush.Color = e.CellStyle.SelectionBackColor; // fontBrush.Color = e.CellStyle.SelectionForeColor; // }// e.Graphics.FillRectangle(backBrush, e.CellBounds); //new Rectangle(e.CellBounds.X,e.CellBounds.Y-(countU-1) * cellheight,cellwidth,cellheight*countU));
// //e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (countU - 1) + (cellheight * count - fontheight) / 2);
// e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - heightU + (totalheight - fontheight) / 2);// if (countD == 1)
// { // e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); // //count = 0; // } // // 画右边线 // e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right-1 , e.CellBounds.Top, e.CellBounds.Right-1 , e.CellBounds.Bottom); // e.Handled = true; //} //else if (e.ColumnIndex == 1 && e.RowIndex != -1) //{ cellheight = e.CellBounds.Height; fontheight = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Height; cellwidth = e.CellBounds.Width; fontwidth = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Width; Pen gridLinePen = new Pen(gridBrush); string curValue = this.Rows[e.RowIndex].Cells[0].Value == null ? "" : this.Rows[e.RowIndex].Cells[0].Value.ToString().Trim(); string curSelected = this.CurrentRow.Cells[0].Value == null ? "" : this.CurrentRow.Cells[0].Value.ToString().Trim(); if (!string.IsNullOrEmpty(curValue)) { for (int i = e.RowIndex; i < this.Rows.Count; i++) { if (this.Rows[i].Cells[0].Value.ToString().Equals(curValue)) { this.Rows[i].Cells[0].Selected = this.Rows[e.RowIndex].Selected; this.Rows[i].Selected = this.Rows[e.RowIndex].Selected; countD++; heightD += this.Rows[i].Height; } else { break; } } for (int i = e.RowIndex; i >= 0; i--) { if (this.Rows[i].Cells[0].Value.ToString().Equals(curValue)) { this.Rows[i].Cells[0].Selected = this.Rows[e.RowIndex].Selected; this.Rows[i].Selected = this.Rows[e.RowIndex].Selected; heightU += this.Rows[i].Height; countU++; } else { break; } } heightU = heightU - e.CellBounds.Height; totalheight = heightU + heightD; count = countD + countU - 1; if (count < 2) { return; } }if (this.Rows[e.RowIndex].Selected)
{ backBrush.Color = e.CellStyle.SelectionBackColor; fontBrush.Color = e.CellStyle.SelectionForeColor; }e.Graphics.FillRectangle(backBrush, e.CellBounds); //new Rectangle(e.CellBounds.X,e.CellBounds.Y-(countU-1) * cellheight,cellwidth,cellheight*countU));
//e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (countU - 1) + (cellheight * count - fontheight) / 2);
string cellvalue = e.Value.ToString(); if (fontwidth > cellwidth) { for (int i = cellvalue.Length-1; i > 0; i--) { cellvalue = cellvalue.Substring(0, i); fontwidth = (int)e.Graphics.MeasureString(cellvalue,e.CellStyle.Font).Width; if (fontwidth <= cellwidth) break; } } e.Graphics.DrawString(cellvalue, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - heightU + (totalheight - fontheight) / 2); if (countD == 1) { e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); //count = 0; }// 画右边线
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right-1, e.CellBounds.Top, e.CellBounds.Right-1, e.CellBounds.Bottom); if(e.ColumnIndex==0)e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left , e.CellBounds.Top, e.CellBounds.Left , e.CellBounds.Bottom); //GraphicsPath mypath = new GraphicsPath(); //StringFormat sf = new StringFormat(); //sf.Alignment = StringAlignment.Center; //mypath.AddString((string)e.Value, e.CellStyle.Font.FontFamily, (int)FontStyle.Regular, e.CellStyle.Font.Size * count, new PointF(e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - heightU + (totalheight - fontheight) / 2), sf); //PointF[] pathpoints = mypath.PathPoints; //byte[] pathbyte = mypath.PathTypes; //e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; //e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; //e.Graphics.FillPath(fontBrush, mypath); e.Handled = true; } //else //{ // // 对第2列相同单元格进行合并 // if (e.ColumnIndex == 1 && e.RowIndex != -1) // { // h = e.CellBounds.Height; // wh = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Height;// using (Pen gridLinePen = new Pen(gridBrush))
// { // // 清除单元格 // e.Graphics.FillRectangle(backBrush, e.CellBounds); // // 画 Grid 边线(仅画单元格的底边线和右边线) // //如果本行的港口画了一条底边线,则在当前的单元格画一条底边线,并填充数据 // if (flag == 1) // { // e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);// e.Graphics.DrawString(e.Value == null ? "" : e.Value.ToString(), e.CellStyle.Font, Brushes.Black, e.CellBounds.X + 2, e.CellBounds.Y + h - (h * count2 - wh) / 2 - wh);
// count2 = 1;
// flag = 0;
// }
// else // { // count2 = count2 + 1; // } // // 画右边线 // e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, e.CellBounds.Top, e.CellBounds.Right - 1, e.CellBounds.Bottom);// }
// e.Handled = true; // } //} } protected override void OnSelectionChanged(EventArgs e) { try { base.OnSelectionChanged(e); if (this.SelectedRows.Count < 1) return; string curvalue = this.CurrentRow.Cells[0].Value.ToString(); foreach(DataGridViewRow dgvr in this.SelectedRows) { if (!dgvr.Cells[0].Value.ToString().Equals( curvalue)) { dgvr.Selected = false; } } } catch { } } protected override void OnCellClick(DataGridViewCellEventArgs e) { base.OnCellClick(e); if(e.RowIndex>-1) this.Rows[e.RowIndex].Cells[0].Selected = true; } protected override void OnRowHeightChanged(DataGridViewRowEventArgs e) { Graphics g=Graphics.FromHwnd(this.Handle); float fornheight = g.MeasureString(e.Row.Cells[0].Value.ToString(), e.Row.InheritedStyle.Font).Height; if (e.Row.Height <= fornheight) e.Row.Height = (int)fornheight; base.OnRowHeightChanged(e); this.Refresh(); }}