Click here to Skip to main content
15,067,539 members
Please Sign up or sign in to vote.
4.50/5 (4 votes)
Is embodiment available like that picture?

Posted
Updated 31-Jan-11 0:14am
v2
Comments
jitendra2009 2 9-May-12 8:02am
   
no
killer_ism 6-Mar-13 1:00am
   
Sorry for my English... How fix a bug, when I use horizontal scrolling?

I think, it will be better if you merge tables first and then bind Gridview to that table.
   
Comments
gksdy2000 31-Jan-11 6:13am
   
Sorry. this is DataGridView in winforms.
I modified and it works
( set DataGridViewCellStyle { WrapMode=True })

C#
void Compare()
       {
           DataTable dt = GetDataTable();
           DataView dv = new DataView(dt);
           String strAtual = String.Empty;
           foreach (DataRowView row in dv)
           {
               if (strAtual.Equals(row.Row["OrderId"].ToString()))
               {
                   foreach (DataColumn dataColumn in dv.Table.Columns)
                   {
                       String columnName = (dataColumn.ColumnName);
                       if (columnName != "OrderId")
                       {
                           string strTagNumb = row[columnName].ToString();
                           CompareDelete(strTagNumb, strAtual, dv, columnName);
                       }
                   }
                   row.Delete();
                   continue;
               }
               if (!string.IsNullOrEmpty(row.Row["OrderId"].ToString()))
                   strAtual = row.Row["OrderId"].ToString();
           }

           dataGridView2.DataSource = dv;
       }

       private void CompareDelete(string strTagNumb, string strAtual, DataView dt, String columnName)
       {
           foreach (DataRowView row in dt)
           {
               if (row.Row["OrderId"].ToString().Equals(strAtual))
               {
                   string nl = Environment.NewLine;
                   row.Row[columnName] += string.Concat(nl, strTagNumb);
                   return;
               }
           }
       }
   
Thanks for the good question. I provided you with links in my answer above. But I've also tried to solve this problem by myself.
The following code demonstrates how you can merge cells and keep it megred even if user selects merged cell.
Merging mode will be turned on after button "Merge" is clicked.
This is just the EXAMPLE(wrote by 10-15 minutes :) ) of possible solution - improve it as you wish.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication2
{
    public partial class Form1 : Form
    {
        DataGridView dataGrid;
        DataSet dataSet;
        Button button;

        private List<string> MergedRowsInFirstColumn = new List<string>();
        private bool readyToMerge = false;


        public Form1()
        {
            InitializeComponent();
            CreateGridAndButton();
        }

        private void CreateGridAndButton()
        {
            dataGrid = new DataGridView();
            dataSet = new DataSet();

            dataGrid.Height = this.Height - 100;
            dataGrid.Dock = DockStyle.Top;
            dataGrid.ReadOnly = true;
            dataGrid.AllowUserToAddRows = false;
            dataGrid.AllowUserToResizeRows = false;
            dataGrid.RowHeadersVisible = false;
            this.dataGrid.Paint += new PaintEventHandler(dataGrid_Paint);

            this.Controls.Add(this.dataGrid);

            button = new Button();
            button.Text = "Merge";
            button.Dock = DockStyle.Bottom;
            button.Click += new System.EventHandler(this.button_Click);

            this.Controls.Add(this.button);

            DataTable tbl_main = new DataTable("tbl_main");

            tbl_main.Columns.Add("Manufacture");
            tbl_main.Columns.Add("Name");
            tbl_main.Columns.Add("CPU");
            tbl_main.Columns.Add("RAM");
            tbl_main.Columns.Add("Price");

            DataRow row;

            row = tbl_main.NewRow();
            row["Manufacture"] = "Dell";
            row["Name"] = "Inspiron 1525";
            row["CPU"] = "T7250";
            row["RAM"] = "2048 MB";
            row["Price"] = "$654";
            tbl_main.Rows.Add(row);

            row = tbl_main.NewRow();
            row["Manufacture"] = "Dell";
            row["Name"] = "Inspiron 1525";
            row["CPU"] = "T5750";
            row["RAM"] = "2048 MB";
            row["Price"] = "$690";
            tbl_main.Rows.Add(row);

            row = tbl_main.NewRow();
            row["Manufacture"] = "Dell";
            row["Name"] = "Studio 1535";
            row["CPU"] = "T5750";
            row["RAM"] = "2048 MB";
            row["Price"] = "$735";
            tbl_main.Rows.Add(row);

            row = tbl_main.NewRow();
            row["Manufacture"] = "Dell";
            row["Name"] = "Vostro 1510";
            row["CPU"] = "T5870";
            row["RAM"] = "2048 MB";
            row["Price"] = "$724";
            tbl_main.Rows.Add(row);

            row = tbl_main.NewRow();
            row["Manufacture"] = "HP";
            row["Name"] = "530";
            row["CPU"] = "T5200";
            row["RAM"] = "1024 MB";
            row["Price"] = "$545";
            tbl_main.Rows.Add(row);

            row = tbl_main.NewRow();
            row["Manufacture"] = "HP";
            row["Name"] = "6720s";
            row["CPU"] = "T5670";
            row["RAM"] = "1024 MB";
            row["Price"] = "$637";
            tbl_main.Rows.Add(row);

            row = tbl_main.NewRow();
            row["Manufacture"] = "HP";
            row["Name"] = "Pavilion dv9233";
            row["CPU"] = "T5670";
            row["RAM"] = "1024 MB";
            row["Price"] = "$780";
            tbl_main.Rows.Add(row);

            dataSet.Tables.Add(tbl_main);
            dataGrid.DataSource = dataSet;
            dataGrid.DataMember = "tbl_main";
        }

        private void dataGrid_Paint(object sender, PaintEventArgs e)
        {
            if (readyToMerge)
            {
                Merge();
            }
        }

        private void button_Click(object sender, EventArgs e)
        {
            Merge();
            readyToMerge = true;
        }

        private bool isSelectedCell(int[] Rows, int ColumnIndex)
        {
            if (dataGrid.SelectedCells.Count > 0)
            {
                for (int iCell = Rows[0]; iCell <= Rows[1]; iCell++)
                {
                    for (int iSelCell = 0; iSelCell < dataGrid.SelectedCells.Count; iSelCell++)
                    {
                        if (dataGrid.Rows[iCell].Cells[ColumnIndex] == dataGrid.SelectedCells[iSelCell])
                        {
                            return true;
                        }
                    }
                }
                return false;
            }
            else
            {
                return false;
            }
        }

        private void Merge()
        {
            int[] RowsToMerge = new int[2];
            RowsToMerge[0] = -1;

            //Merge first column at first
            for (int i = 0; i < dataSet.Tables["tbl_main"].Rows.Count - 1; i++)
            {
                if (dataSet.Tables["tbl_main"].Rows[i]["Manufacture"] == dataSet.Tables["tbl_main"].Rows[i + 1]["Manufacture"])
                {
                    if (RowsToMerge[0] == -1)
                    {
                        RowsToMerge[0] = i;
                        RowsToMerge[1] = i + 1;
                    }
                    else
                    {
                        RowsToMerge[1] = i + 1;
                    }
                }
                else
                {
                    MergeCells(RowsToMerge[0], RowsToMerge[1], dataGrid.Columns["Manufacture"].Index, isSelectedCell(RowsToMerge, dataGrid.Columns["Manufacture"].Index) ? true : false);
                    CollectMergedRowsInFirstColumn(RowsToMerge[0], RowsToMerge[1]);
                    RowsToMerge[0] = -1;
                }
                if (i == dataSet.Tables["tbl_main"].Rows.Count - 2)
                {
                    MergeCells(RowsToMerge[0], RowsToMerge[1], dataGrid.Columns["Manufacture"].Index, isSelectedCell(RowsToMerge, dataGrid.Columns["Manufacture"].Index) ? true : false);
                    CollectMergedRowsInFirstColumn(RowsToMerge[0], RowsToMerge[1]);
                    RowsToMerge[0] = -1;
                }
            }
            if (RowsToMerge[0] != -1)
            {
                MergeCells(RowsToMerge[0], RowsToMerge[1], dataGrid.Columns["Manufacture"].Index, isSelectedCell(RowsToMerge, dataGrid.Columns["Manufacture"].Index) ? true : false);
                RowsToMerge[0] = -1;
            }

            //merge all other columns
            for (int iColumn = 1; iColumn < dataSet.Tables["tbl_main"].Columns.Count - 1; iColumn++)
            {
                for (int iRow = 0; iRow < dataSet.Tables["tbl_main"].Rows.Count - 1; iRow++)
                {
                    if ((dataSet.Tables["tbl_main"].Rows[iRow][iColumn] == dataSet.Tables["tbl_main"].Rows[iRow + 1][iColumn]) &&
                         (isRowsHaveOneCellInFirstColumn(iRow, iRow + 1)))
                    {
                        if (RowsToMerge[0] == -1)
                        {
                            RowsToMerge[0] = iRow;
                            RowsToMerge[1] = iRow + 1;
                        }
                        else
                        {
                            RowsToMerge[1] = iRow + 1;
                        }
                    }
                    else
                    {
                        if (RowsToMerge[0] != -1)
                        {
                            MergeCells(RowsToMerge[0], RowsToMerge[1], iColumn, isSelectedCell(RowsToMerge, iColumn) ? true : false);
                            RowsToMerge[0] = -1;
                        }
                    }
                }
                if (RowsToMerge[0] != -1)
                {
                    MergeCells(RowsToMerge[0], RowsToMerge[1], iColumn, isSelectedCell(RowsToMerge, iColumn) ? true : false);
                    RowsToMerge[0] = -1;
                }
            }
        }

        private bool isRowsHaveOneCellInFirstColumn(int RowId1, int RowId2)
        {

            foreach (string rowsCollection in MergedRowsInFirstColumn)
            {
                string[] RowsNumber = rowsCollection.Split(';');

                if ((isStringInArray(RowsNumber,RowId1.ToString())) &&
                    (isStringInArray(RowsNumber,RowId2.ToString())))
                {
                    return true;
                }
            }
            return false;
        }
        
        private bool isStringInArray(string[] Array, string value)
        {
            foreach (string item in Array)
            {
                if (item == value)
                {
                    return true;
                } 
                
            }
            return false;
        }

        private void CollectMergedRowsInFirstColumn(int RowId1, int RowId2)
        {
            string MergedRows = String.Empty;

            for (int i = RowId1; i <= RowId2; i++)
            {
                MergedRows += i.ToString() + ";";
            }
            MergedRowsInFirstColumn.Add(MergedRows.Remove(MergedRows.Length - 1, 1));
        }

        private void MergeCells(int RowId1, int RowId2, int Column, bool isSelected)
        {
            Graphics g = dataGrid.CreateGraphics();
            Pen gridPen = new Pen(dataGrid.GridColor);

            //Cells Rectangles
            Rectangle CellRectangle1 = dataGrid.GetCellDisplayRectangle(Column, RowId1, true);
            Rectangle CellRectangle2 = dataGrid.GetCellDisplayRectangle(Column, RowId2, true);

            int rectHeight = 0;
            string MergedRows= String.Empty;

            for (int i = RowId1; i <= RowId2; i++)
            {
                rectHeight += dataGrid.GetCellDisplayRectangle(Column, i, false).Height;
            }

            Rectangle newCell = new Rectangle(CellRectangle1.X, CellRectangle1.Y, CellRectangle1.Width, rectHeight);

            g.FillRectangle(new SolidBrush(isSelected ? dataGrid.DefaultCellStyle.SelectionBackColor : dataGrid.DefaultCellStyle.BackColor), newCell);

            g.DrawRectangle(gridPen, newCell);

            g.DrawString(dataGrid.Rows[RowId1].Cells[Column].Value.ToString(), dataGrid.DefaultCellStyle.Font, new SolidBrush(isSelected? dataGrid.DefaultCellStyle.SelectionForeColor: dataGrid.DefaultCellStyle.ForeColor), newCell.X + newCell.Width / 3, newCell.Y + newCell.Height / 3 );
        }
    }
}
</string></string>
   
Comments
gksdy2000 1-Feb-11 18:47pm
   
Oh~ This is code that I find.
It became big help.
Thank.
TimGameDev 2-Feb-11 1:36am
   
You are welcome :)
Rashrak 27-May-14 3:45am
   
Hi Timur Akhmedov , Thank you soo much , Your code helped me a lot. But I'm facing a problem.My datagridview have a column with checkbox , when I merge the cells of that column it shows only value like 'True'/'False'. My requirement is to show a single checkbox column for the entire row that I merged. Hope you got what I asked.
IndrajitDasgupat 13-Aug-12 1:28am
   
If Data Grid View generating in Run Time Auto generated it is showing error in your code in the below line
else
{
MergeCells(RowsToMerge[0], RowsToMerge[1], dataGrid.Columns["Rack"].Index, isSelectedCell(RowsToMerge, dataGrid.Columns["Rack"].Index) ? true : false);
CollectMergedRowsInFirstColumn(RowsToMerge[0], RowsToMerge[1]);
RowsToMerge[0] = -1;
}
Member 11776570 18-Apr-18 12:18pm
   
If i want to add new rows in data grid view, but if data grid already has a data. So how can i add new rows without removing the previous one.
Hi,

I did it a few weeks ago, follow the cobe below:

C#
using (DataTable dt = new DataTable())
                {
                    adapter.Fill(dt);
                    DataView dv = new DataView(dt);
                    String strAtual = String.Empty;
                    //Percorrer o DataTable
                    foreach (DataRowView row in dv)
                    {
                        if (strAtual.Equals(row.Row["OrderId"].ToString()))
                        {
                            string strTagNumb = row["TagList"].ToString();
                            CompareDelete(strTagNumb, strAtual, dv);
                            row.Delete();
                            continue;
                        }
                        if (!string.IsNullOrEmpty(row.Row["OrderId"].ToString()))
                            strAtual = row.Row["OrderId"].ToString();
                    }

                    intTotal = dv.Count;
                    gvSchedules.DataSource = dv;
                    gvSchedules.DataBind();
                }

   private void CompareDelete(string strTagNumb, string strAtual, DataView dt)
    {
        foreach (DataRowView row in dt)
        {
            if (row.Row["OrderId"].ToString().Equals(strAtual))
            {
                row.Row["TagList"] += string.Concat("</br>", strTagNumb);
                return;
            }
        }
    }



Hope that helps.
felipekm.com
   
Comments
TimGameDev 31-Jan-11 9:22am
   
Could you elaborate how does it work? I don't see cells merging here...
--
Timur
felipekm 31-Jan-11 11:00am
   
Sure,
Actually in this case I did merged Rows.

You have to iterate into the cell, saving the first one a some variable, after that you have to match this variable (previous data) with the actual iterate data, if this is true, you have to concatenate and delete the row, implement the same logic with these cells like I did.

If you need a workaround please post your code.
Cheers,
gksdy2000 31-Jan-11 16:57pm
   
Maybe, is this grid in Web?
Grid of the question is in Winforms.
felipekm 31-Jan-11 20:45pm
   
Yes, it is.
But the logic still the same. If you post your code will be better.
IndrajitDasgupat 13-Aug-12 1:42am
   
gvSchedules what is this in your code please define
Raman Midha 28-Jun-13 5:01am
   
when i use scroll bar for datagridview then its not working
Merging cells in DataGridView is difficult thing because there are no standard ways to do this:
http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/fea3dcff-5447-450a-8f7c-bb1c4f63371d/[^]

Here is solution I found:
http://www.codeguru.com/forum/showthread.php?t=415930[^]

But if you still want to do this - algorithm should be easy:
1. Merge cells in First column
2. Merge cells in rest of columns which have the same cell in first column

Hope this will help ;)
--
Timur
   
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900