您的位置:首页 > 其它

VS2005的DataGridView 表头合并处理

2008-09-18 10:46 351 查看
前几天Jo Muncher's Blog上看到《VS2005的DataGridView 多维合并标题 功能拓展》的文章,对我制作DataGridView多表头大有帮助,并把代码进行了调试,发现还有问题。近日把VB代码修改成C#代码,并对部分BUG进行修改,最终还是把问题攻克了,效果比较理想。见下图



源代码如下:

HeaderUnitView.cs


using System;


using System.Collections;


using System.Collections.Generic;


using System.Data.Sql;


using System.Text;


using System.Drawing;


using System.Drawing.Design;


using System.Windows.Forms;


using System.Windows.Forms.VisualStyles;


using System.ComponentModel;


using System.ComponentModel.Design;


using System.ComponentModel.Design.Serialization;


using System.Diagnostics;


using System.Runtime.InteropServices;




namespace DataGridViewSampCs




...{


public partial class HeaderUnitView : DataGridView




...{


private TreeView[] _columnTreeView;


private ArrayList _columnList = new ArrayList();


private int _cellHeight = 17;


private int _columnDeep = 1;








/**//// <summary>


/// 构造函数


/// </summary>


public HeaderUnitView()




...{


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]; }


}




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


// , Brushes.Black


// , uhRectangle


// , textFormat);


e.Graphics.DrawString(node.Text, this.Font


, Brushes.Black


, 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 Boolean IsSingleChildNode(TreeNode node)


//{


// if (node.Nodes == null)


// return false;




// if (node.Nodes.Count == 0)


// return false;




// if (node.Nodes.Count == 1)


// return true;


// return false;


//}








/**//// <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>


/// <remarks></remarks>


protected override void OnCellPainting(System.Windows.Forms.DataGridViewCellPaintingEventArgs e)




...{


//行标题不重写


if (e.ColumnIndex < 0)




...{


base.OnCellPainting(e);


return;


}




if (_columnDeep == 1)




...{


base.OnCellPainting(e);


return;


}




//绘制表头


if (e.RowIndex == -1)




...{


PaintUnitHeader((TreeNode)NadirColumnList[e.ColumnIndex]


,e


, _columnDeep);


e.Handled = true;


}


}






}


}



HeaderUnitView.Designer.cs(修改Dispose事件中的代码,其它的不用修改)




/**//// <summary>


/// 清理所有正在使用的资源。


/// </summary>


/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>


protected override void Dispose(bool disposing)




...{


if (_columnTreeView != null)




...{


for (int i = 0; i <= _columnTreeView.Length - 1; i++)




...{


_columnTreeView[i].Dispose();


}


}




if (disposing && (components != null))




...{


components.Dispose();


}


base.Dispose(disposing);


}

由于是Jo Muncher's 文章,这里不再多说了,如想知道更多,请点击下面连接。

http://blog.csdn.net/JoMuncher/archive/2007/11/02/1862977.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: