VS2005的DataGridView 多维合并标题

前几天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

评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值