DataGridView 다 중 열 헤더,병합 셀

DataGridView 확장 기능 다 중 행렬 헤드,병합 셀
http://blog.sina.com.cn/s/blog_63160fa801014ity.html
 
 public partial class ExtDataGridView : DataGridView
    {
        #region   、  
        /// 
        ///      
        /// 
        private TreeView _columnTreeView = null;

        /// 
        /// DataGirdView 
        /// 
        private ArrayList _columnList = new ArrayList();

        /// 
        ///      
        /// 
        private int _cellHeight = 17;

        /// 
        ///           
        /// 
        public int CellHeight
        {
            get { return _cellHeight; }
            set { _cellHeight = value; }
        }

        private List _mergecolumnname = new List();

        /// 
        ///     
        /// 
        private int _columnDeep = 1;

        /// 
        ///      
        /// 
        private bool _hscrollRefresh = false;

        ///   
        ///            ,          ,            
        ///   
        [Description("           ,          ,          ")]
        public bool RefreshAtHscroll
        {
            get { return _hscrollRefresh; }
            set { _hscrollRefresh = value; }
        }

        [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
            {
                _columnTreeView = value;
            }
        }

        [Description("             ")]
        public TreeView ColumnTreeViewNode
        {
            get
            {
                if (_columnTreeView == null)
                    return null;
                return _columnTreeView;
            }
        }

        /// 
        ///            
        /// 
        [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;
            }
        }

        /// 
        ///            
        /// 
        public ArrayList NadirColumnList
        {
            get
            {
                if (_columnTreeView == null)
                    return null;
                //if (_columnTreeView[0] == null)
                //    return null;
                if (_columnTreeView.Nodes == null)
                    return null;
                if (_columnTreeView.Nodes.Count == 0)
                    return null;
                _columnList.Clear();
                GetNadirColumnNodes(_columnList, _columnTreeView.Nodes[0], false);
                return _columnList;
            }
        }

        #endregion

        #region     
        /// 
        ///   DataGridView    
        /// 
        public ExtDataGridView()
        {
            InitializeComponent();
            this.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
            //                       
            //      
            base.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            //      DataGrid
            //base.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
        }
        #endregion

        #region   
        ///  
        ///        
        ///  
        ///        
        ///       
        ///      
        ///  
        public void PaintUnitHeader(TreeNode node, 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;
            int index = 0;
            //            
            if (node.Nodes == null || node.Nodes.Count == 0)
            {
                index = GetColumnListNodeIndex(node);
                if (this.Columns.Count > index)
                    return this.Columns[index].Width;
                else
                    return uhWidth;
            }
            //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;
                    }
                }
            }
        }
        #endregion

        #region     
        ///   
        ///      (  )  
        ///   
        ///   
        ///   
        protected override void OnCellPainting(System.Windows.Forms.DataGridViewCellPaintingEventArgs e)
        {
            try
            {
                if (e.RowIndex > -1 && e.ColumnIndex > -1 && MergeColumnNames.Count > 0)
                {
                    MergeCell(e);
                }
                else if (_columnTreeView != null && _columnTreeView.Nodes.Count > 0)
                {
                    //        
                    if (e.ColumnIndex < 0)
                    {
                        base.OnCellPainting(e);
                        return;
                    }
                    if (_columnDeep == 1)
                    {
                        base.OnCellPainting(e);
                        return;
                    }
                    //      
                    if (e.RowIndex == -1 && NadirColumnList != null)
                    {
                        if (e.ColumnIndex >= NadirColumnList.Count) { e.Handled = true; return; }
                        PaintUnitHeader((TreeNode)NadirColumnList[e.ColumnIndex]
                                        , e
                                        , _columnDeep);
                        e.Handled = true;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        ///   
        ///      
        ///   
        ///   
        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);
            //float uwh = g.MeasureString(e.Column.HeaderText, this.Font).Width;
            //if (uwh >= e.Column.Width) { e.Column.Width = Convert.ToInt16(uwh); }

            if (MergeColumnNames.Count > 0 ||
                (_columnTreeView != null && _columnTreeView.Nodes.Count > 0))
            {
                this.Refresh();
            }
            base.OnColumnWidthChanged(e);
        }

        /// 
        ///       
        /// 
        /// 
        protected override void OnCellValueChanged(DataGridViewCellEventArgs e)
        {
            string colName = this.Columns[e.ColumnIndex].Name;
            if (this.MergeColumnNames.Contains(colName))
                this.Refresh();
            base.OnCellValueChanged(e);
        }
        #endregion

        #region      
        /// 
        ///     
        /// 
        /// 
        private void MergeCell(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 != null && 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 != null &&
                            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);

                if (e.RowIndex == this.Rows.Count - 1)
                    e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
                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 == null ? string.Empty : e.Value.ToString(), e.CellStyle.Font).Height;
            int fontwidth = (int)e.Graphics.MeasureString(e.Value == null ? string.Empty : 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

        private void InitializeComponent()
        {
            ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
            this.SuspendLayout();
            // 
            // HeaderUnitView
            // 
            this.RowTemplate.Height = 23;
            ((System.ComponentModel.ISupportInitialize)(this)).EndInit();
            this.ResumeLayout(false);

        }
    }

 

좋은 웹페이지 즐겨찾기