简体   繁体   中英

merging columns in datagridview in c#

i have a datagridview on my c# winforms and i want to merge some columns to enter data on it. how will i do that?

this is my code:

private void General_Inventory_Load(object sender, EventArgs e)
        {

            dgvGenInventory.Columns.Add("JanWin", "Win");
            dgvGenInventory.Columns.Add("JanLoss", "Loss");
            dgvGenInventory.Columns.Add("FebWin", "Win");
            dgvGenInventory.Columns.Add("FebLoss", "Loss");
            dgvGenInventory.Columns.Add("MarWin", "Win");
            dgvGenInventory.Columns.Add("MarLoss", "Loss");
            dgvGenInventory.Columns.Add("AprWin", "Win");
            dgvGenInventory.Columns.Add("AprLoss", "Loss");

            dgvGenInventory.Rows.Add("1", "2", "3", "2", "2", "2", "4", "2");
            for (int i = 0; i < dgvGenInventory.ColumnCount - 1; i++)
            {
                dgvGenInventory.Columns[i].Width = 45;
            }
        this.dgvGenInventory.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
        this.dgvGenInventory.ColumnHeadersHeight = this.dgvGenInventory.ColumnHeadersHeight * 2;
        this.dgvGenInventory.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomCenter;
        this.dgvGenInventory.CellPainting += new DataGridViewCellPaintingEventHandler(dgvGenInventory_CellPainting);
        this.dgvGenInventory.Paint += new PaintEventHandler(dgvGenInventory_Paint);
        this.dgvGenInventory.Scroll += new ScrollEventHandler(dgvGenInventory_Scroll);
        this.dgvGenInventory.ColumnWidthChanged += new DataGridViewColumnEventHandler(dgvGenInventory_ColumnWidthChanged);

        }

        private void dgvGenInventory_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.RowIndex == -1 && e.ColumnIndex > -1)
            {
                Rectangle r2 = e.CellBounds;
                r2.Y += e.CellBounds.Height / 2;
                r2.Height = e.CellBounds.Height / 2;
                e.PaintBackground(r2, true);
                e.PaintContent(r2);
                e.Handled = true;
            }
        }

I think, it will be better if you merge data in table first and then bind DataGridview to that table.

try this:

        private void Form1_Load(object sender, EventArgs e)
        {
            m_BuildGrid();
        }

        private void m_BuildGrid()
        {
            DataGridViewColumn pColumn;
            int i, j;
            String strTemp;
            HMergedCell pCell;
            int nOffset;

            dataGridView2.Columns.Add(@"colGroup", @"");
            dataGridView2.Columns.Add(@"colTask", @"Task");
            pColumn = dataGridView2.Columns["colTask"];
            pColumn.Frozen = true;

            for (i = 0; i < 25; i++)
            {
                strTemp = "col" + i.ToString();
                dataGridView2.Columns.Add(@strTemp, i.ToString());
                pColumn = dataGridView2.Columns[strTemp];
                pColumn.SortMode = DataGridViewColumnSortMode.NotSortable;
                pColumn.Width = 40;
            }

            dataGridView2.Rows.Add(20);

            nOffset = 2;
            for (i = 0; i < 3; i++)
            {
                for (j = nOffset; j < nOffset + 7; j++)
                {
                    dataGridView2.Rows[0].Cells[j] = new HMergedCell();
                    pCell = (HMergedCell)dataGridView2.Rows[0].Cells[j];
                    pCell.LeftColumn = nOffset;
                    pCell.RightColumn = nOffset + 6;
                }
                nOffset += 7;
            }


            for (i = 0; i < 20; i++)
                for (j = 0; j < 22; j++)
                {
                    dataGridView2.Rows[i].Cells[j].Value = "{" + i.ToString() + "," + j.ToString() + "}";
                }

            pColumn = null;
        }
    }

and add this class to your project

    public class HMergedCell : DataGridViewTextBoxCell
    {
        private int m_nLeftColumn = 0;
        private int m_nRightColumn = 0;

        /// <summary>
        /// Column Index of the left-most cell to be merged.
        /// This cell controls the merged text.
        /// </summary>
        public int LeftColumn
        {
            get
            {
                return m_nLeftColumn;
            }
            set
            {
                m_nLeftColumn = value;
            }
        }

        /// <summary>
        /// Column Index of the right-most cell to be merged
        /// </summary>
        public int RightColumn
        {
            get
            {
                return m_nRightColumn;
            }
            set
            {
                m_nRightColumn = value;
            }
        }

        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            try
            {
                int mergeindex = ColumnIndex - m_nLeftColumn;
                int i;
                int nWidth;
                int nWidthLeft;
                string strText;

                Pen pen = new Pen(Brushes.Black);

                // Draw the background
                graphics.FillRectangle(new SolidBrush(SystemColors.Control), cellBounds);

                // Draw the separator for rows
                graphics.DrawLine(new Pen(new SolidBrush(SystemColors.ControlDark)), cellBounds.Left, cellBounds.Bottom - 1, cellBounds.Right, cellBounds.Bottom - 1);

                // Draw the right vertical line for the cell
                if (ColumnIndex == m_nRightColumn)
                    graphics.DrawLine(new Pen(new SolidBrush(SystemColors.ControlDark)), cellBounds.Right - 1, cellBounds.Top, cellBounds.Right - 1, cellBounds.Bottom);

                // Draw the text
                RectangleF rectDest = RectangleF.Empty;
                StringFormat sf = new StringFormat();
                sf.Alignment = StringAlignment.Center;
                sf.LineAlignment = StringAlignment.Center;
                sf.Trimming = StringTrimming.EllipsisCharacter;

                // Determine the total width of the merged cell
                nWidth = 0;
                for (i = m_nLeftColumn; i <= m_nRightColumn; i++)
                    nWidth += this.OwningRow.Cells[i].Size.Width;

                // Determine the width before the current cell.
                nWidthLeft = 0;
                for (i = m_nLeftColumn; i < ColumnIndex; i++)
                    nWidthLeft += this.OwningRow.Cells[i].Size.Width;

                // Retrieve the text to be displayed
                strText = this.OwningRow.Cells[m_nLeftColumn].Value.ToString();

                rectDest = new RectangleF(cellBounds.Left - nWidthLeft, cellBounds.Top, nWidth, cellBounds.Height);
                graphics.DrawString(strText, new Font("Arial", 10, FontStyle.Regular), Brushes.Black, rectDest, sf);
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.ToString());
            }
        }

    }

I spent a long time looking for this as my boss didn't want to buy any off-the-shelf components. This should be submitted into the .NET code: datagridvewtextboxcell-with-span-behaviour It just works and is soo simple to use. Works with VB/C# .NET 4.5 to 6.

DataGridView.Columns.Add(new DataGridViewTextBoxColumnEx());
var dataGridViewCell = (DataGridViewTextBoxCellEx)DataGridView[colIdx, rowIdx];
dataGridViewCell.ColSpan = 2;
dataGridViewCell.RowSpan = 6;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM