转:VS2005的DataGridView 多维合并标题 功能拓展

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

转:VS2005的DataGridView 多维合并标题 功能拓展_第1张图片

源代码如下:

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

你可能感兴趣的:(datagridview)