using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Drawing; using System.Drawing.Design; using System.Diagnostics; namespace JDFShowSystem { public partial class MDataGridView : 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; /// /// 水平滚动时是否刷新表头,数据较多时可能会闪烁,不刷新时可能显示错误 /// [Description("水平滚动时是否刷新表头,数据较多时可能会闪烁,不刷新时可能显示错误")] public bool RefreshAtHscroll { get { return HscrollRefresh; } set { HscrollRefresh = value; } } /// /// 构造函数 /// public MDataGridView() { InitializeComponent(); this.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing; //设置列高度显示模式 } public MDataGridView(IContainer container) { container.Add(this); InitializeComponent(); } [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]; } } /// /// 设置或获取合并列的集合 /// [MergableProperty(false)] [Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] [DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Visible)] [Localizable(true)] [Description("设置或获取合并列的集合"), Browsable(true), Category("单元格合并")] public List MergeColumnNames { get { return _mergecolumnname; } set { _mergecolumnname = value; } } private List _mergecolumnname = new List(); 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; } } /// ///绘制合并表头 /// ///合并表头节点 ///绘图参数集 ///结点深度 /// 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); //递归调用() if (node.PrevNode == null) if (node.Parent != null) PaintUnitHeader(node.Parent, e, level - 1); } /// /// 获得合并标题字段的宽度 /// /// 字段节点 /// 字段宽度 /// 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; } /// /// 获得底层字段索引 /// ///' 底层字段节点 /// 索引 /// private int GetColumnListNodeIndex(TreeNode node) { for (int i = 0; i <= _columnList.Count - 1; i++) { if (((TreeNode)_columnList[i]).Equals(node)) return i; } return -1; } /// /// 获得底层字段集合 /// /// 底层字段集合 /// 字段节点 /// 向上搜索与否 /// 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; } } } } /// /// 滚动 /// /// protected override void OnScroll(ScrollEventArgs e) { bool scrollDirection = (e.ScrollOrientation == ScrollOrientation.HorizontalScroll); base.OnScroll(e); if (RefreshAtHscroll && scrollDirection) this.Refresh(); } /// /// 列宽度改变的重写 /// /// protected override void OnColumnWidthChanged(DataGridViewColumnEventArgs e) { Graphics g = Graphics.FromHwnd(this.Handle); try { float uwh = g.MeasureString(e.Column.HeaderText, this.Font).Width; if (uwh >= e.Column.Width) { e.Column.Width = Convert.ToInt16(uwh); } base.OnColumnWidthChanged(e); } catch { } } /// /// 单元格绘制(重写) /// /// /// protected override void OnCellPainting(System.Windows.Forms.DataGridViewCellPaintingEventArgs e) { try { if (e.RowIndex > -1 && e.ColumnIndex > -1) { DrawCell(e); } else { //行标题不重写 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 { } } #region 合并单元格 /// /// 画单元格 /// /// private void DrawCell(DataGridViewCellPaintingEventArgs e) { if (e.CellStyle.Alignment == DataGridViewContentAlignment.NotSet) { e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; } Brush gridBrush = new SolidBrush(this.GridColor); SolidBrush backBrush = new SolidBrush(e.CellStyle.BackColor); SolidBrush fontBrush = new SolidBrush(e.CellStyle.ForeColor); int cellwidth; //上面相同的行数 int UpRows = 0; //下面相同的行数 int DownRows = 0; //总行数 int count = 0; if (this.MergeColumnNames.Contains(this.Columns[e.ColumnIndex].Name) && e.RowIndex != -1) { cellwidth = e.CellBounds.Width; Pen gridLinePen = new Pen(gridBrush); string curValue = e.Value == null ? "" : e.Value.ToString().Trim(); string curSelected = this.CurrentRow.Cells[e.ColumnIndex].Value == null ? "" : this.CurrentRow.Cells[e.ColumnIndex].Value.ToString().Trim(); if (!string.IsNullOrEmpty(curValue)) { #region 获取下面的行数 for (int i = e.RowIndex; i < this.Rows.Count; i++) { if (this.Rows[i].Cells[e.ColumnIndex].Value.ToString().Equals(curValue)) { //this.Rows[i].Cells[e.ColumnIndex].Selected = this.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected; DownRows++; if (e.RowIndex != i) { cellwidth = cellwidth < this.Rows[i].Cells[e.ColumnIndex].Size.Width ? cellwidth : this.Rows[i].Cells[e.ColumnIndex].Size.Width; } } else { break; } } #endregion #region 获取上面的行数 for (int i = e.RowIndex; i >= 0; i--) { if (this.Rows[i].Cells[e.ColumnIndex].Value.ToString().Equals(curValue)) { //this.Rows[i].Cells[e.ColumnIndex].Selected = this.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected; UpRows++; if (e.RowIndex != i) { cellwidth = cellwidth < this.Rows[i].Cells[e.ColumnIndex].Size.Width ? cellwidth : this.Rows[i].Cells[e.ColumnIndex].Size.Width; } } else { break; } } #endregion count = DownRows + UpRows - 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); //画字符串 PaintingFont(e, cellwidth, UpRows, DownRows, count); if (DownRows == 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; } } /// /// 画字符串 /// /// /// /// /// /// private void PaintingFont(System.Windows.Forms.DataGridViewCellPaintingEventArgs e, int cellwidth, int UpRows, int DownRows, int count) { SolidBrush fontBrush = new SolidBrush(e.CellStyle.ForeColor); int fontheight = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Height; int fontwidth = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Width; int cellheight = e.CellBounds.Height; if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomCenter) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y + cellheight * DownRows - fontheight); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomLeft) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y + cellheight * DownRows - fontheight); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomRight) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y + cellheight * DownRows - fontheight); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleCenter) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleLeft) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleRight) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopCenter) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1)); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopLeft) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y - cellheight * (UpRows - 1)); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopRight) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y - cellheight * (UpRows - 1)); } else { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2); } } #endregion } }