Windows Develop Bookmark and Share   
 index > Windows Forms Data Controls and Databinding > Data Grid view cell merging
 

Data Grid view cell merging

Hi,
I am working on windows application using Vb.Now I want to merge datagridview selected cells.For this purpose I modified your code provided in the Forums.
The code function as you people mentioned.But what happened is the merging will disappear when the Selection removed or we select the region again.

So please provide help for me.

Sample code I pasted below.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

MergeCell(DataGridView2.SelectedCells(0).ColumnIndex, DataGridView2.SelectedCells(DataGridView2.SelectedCells.Count - 1).RowIndex, DataGridView2.SelectedCells.Count)

End Sub


Private Sub MergeCell(ByVal StartColIndx As String, ByVal startRowIndx As Integer, ByVal noofCol As Integer)

Dim r1 As Rectangle = Me.DataGridView2.GetCellDisplayRectangle(StartColIndx + 1, startRowIndx, True)
Dim w2 As Integer = Me.DataGridView2.GetCellDisplayRectangle(StartColIndx, startRowIndx, True).Width

r1.X += 1
r1.Y += 1

r1.Width = r1.Width + 2
r1.Height = (r1.Height * noofCol) + 2

DataGridView2.CreateGraphics.DrawRectangle(New Pen(Color.Black), r1)
r1.X += 1
r1.Y += 1
r1.Width = r1.Width - 1
r1.Height = r1.Height - 1

DataGridView2.CreateGraphics.FillRectangle(New SolidBrush(Color.Wheat), r1)
Dim Format As StringFormat = New StringFormat
Format.Alignment = StringAlignment.Center
Format.LineAlignment = StringAlignment.Center
DataGridView2.CreateGraphics.DrawString("Merged", Me.DataGridView3.ColumnHeadersDefaultCellStyle.Font, New SolidBrush(Color.Blue), r1, Format)
End Sub
Manu Dev  Friday, July 31, 2009 11:04 AM

Hi Manu,

In your code snippet, you drew the merged cell after the button clicking. This can only draw one time. When we select another cell, the DataGridView needs to be drawn again, so the merged cell drawn before would be covered by the cells drawn now.

We can create our own DataGridView to handle the drawing. We can draw the merged cells in the overridden OnPaint method. This is the code snippet:

The custom DataGridView:

'Custom DataGridView
Public Class MyDataGridView
    Inherits DataGridView

    'Data object includes the merge information
    Public Class MergeUnit
        Public StartColIndex As Integer
        Public StartRowIndex As Integer
        Public Count As Integer
    End Class

    'Add a merge unit
    Public Sub Merge(ByVal mu As MergeUnit)
        MergeList.Add(mu)
        Me.Invalidate()
    End Sub
    'Remove a merge unit
    Public Sub Remove(ByVal mu As MergeUnit)
        MergeList.Remove(mu)
        Me.Invalidate()
    End Sub
    'merge unit list.
    Private MergeList As List(Of MergeUnit) = New List(Of MergeUnit)()

    'Override this method to paint merged cells.
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)
        'Draw the merged cells.
        For Each mu As MergeUnit In MergeList
            MergeCell(mu, e.Graphics)
        Next
    End Sub
    'Handle drawing a merged cell.
    Private Sub MergeCell(ByVal mu As MergeUnit, ByVal g As Graphics)

        Dim r1 As Rectangle = Me.GetCellDisplayRectangle(mu.StartColIndex, mu.StartRowIndex, True)
        Dim w2 As Integer = Me.GetCellDisplayRectangle(mu.StartColIndex, mu.StartRowIndex, True).Width

        r1.Width = r1.Width - 1
        r1.Height = (r1.Height * mu.Count) - 1

        g.DrawRectangle(New Pen(Color.Black), r1)
        r1.X += 1
        r1.Y += 1
        r1.Width = r1.Width - 1
        r1.Height = r1.Height - 1

        g.FillRectangle(New SolidBrush(Color.Wheat), r1)
        Dim Format As StringFormat = New StringFormat
        Format.Alignment = StringAlignment.Center
        Format.LineAlignment = StringAlignment.Center
        g.DrawString("Merged", Me.ColumnHeadersDefaultCellStyle.Font, New SolidBrush(Color.Blue), r1, Format)
    End Sub

End Class

The test code in Form:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim startCell As DataGridViewCell = DataGridView2.SelectedCells(DataGridView2.SelectedCells.Count - 1)
        Dim mu As MyDataGridView.MergeUnit = New MyDataGridView.MergeUnit()
        With mu
            .Count = DataGridView2.SelectedCells.Count
            .StartColIndex = startCell.ColumnIndex
            .StartRowIndex = startCell.RowIndex
        End With
        DataGridView2.Merge(mu)
    End Sub

Let me know if this helps.
Aland Li


Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.
Aland Li  Tuesday, August 04, 2009 7:46 AM

Hi Manu,

In your code snippet, you drew the merged cell after the button clicking. This can only draw one time. When we select another cell, the DataGridView needs to be drawn again, so the merged cell drawn before would be covered by the cells drawn now.

We can create our own DataGridView to handle the drawing. We can draw the merged cells in the overridden OnPaint method. This is the code snippet:

The custom DataGridView:

'Custom DataGridView
Public Class MyDataGridView
    Inherits DataGridView

    'Data object includes the merge information
    Public Class MergeUnit
        Public StartColIndex As Integer
        Public StartRowIndex As Integer
        Public Count As Integer
    End Class

    'Add a merge unit
    Public Sub Merge(ByVal mu As MergeUnit)
        MergeList.Add(mu)
        Me.Invalidate()
    End Sub
    'Remove a merge unit
    Public Sub Remove(ByVal mu As MergeUnit)
        MergeList.Remove(mu)
        Me.Invalidate()
    End Sub
    'merge unit list.
    Private MergeList As List(Of MergeUnit) = New List(Of MergeUnit)()

    'Override this method to paint merged cells.
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)
        'Draw the merged cells.
        For Each mu As MergeUnit In MergeList
            MergeCell(mu, e.Graphics)
        Next
    End Sub
    'Handle drawing a merged cell.
    Private Sub MergeCell(ByVal mu As MergeUnit, ByVal g As Graphics)

        Dim r1 As Rectangle = Me.GetCellDisplayRectangle(mu.StartColIndex, mu.StartRowIndex, True)
        Dim w2 As Integer = Me.GetCellDisplayRectangle(mu.StartColIndex, mu.StartRowIndex, True).Width

        r1.Width = r1.Width - 1
        r1.Height = (r1.Height * mu.Count) - 1

        g.DrawRectangle(New Pen(Color.Black), r1)
        r1.X += 1
        r1.Y += 1
        r1.Width = r1.Width - 1
        r1.Height = r1.Height - 1

        g.FillRectangle(New SolidBrush(Color.Wheat), r1)
        Dim Format As StringFormat = New StringFormat
        Format.Alignment = StringAlignment.Center
        Format.LineAlignment = StringAlignment.Center
        g.DrawString("Merged", Me.ColumnHeadersDefaultCellStyle.Font, New SolidBrush(Color.Blue), r1, Format)
    End Sub

End Class

The test code in Form:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim startCell As DataGridViewCell = DataGridView2.SelectedCells(DataGridView2.SelectedCells.Count - 1)
        Dim mu As MyDataGridView.MergeUnit = New MyDataGridView.MergeUnit()
        With mu
            .Count = DataGridView2.SelectedCells.Count
            .StartColIndex = startCell.ColumnIndex
            .StartRowIndex = startCell.RowIndex
        End With
        DataGridView2.Merge(mu)
    End Sub

Let me know if this helps.
Aland Li


Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.
Aland Li  Tuesday, August 04, 2009 7:46 AM
Hai Aland Li,

Thanks for your replay.This solution is apt for my application
Manu Dev  Monday, August 10, 2009 7:01 AM

You can use google to search for other answers

Custom Search

More Threads

• Adding TableAdapters to a form
• MS Access Query On Form Textbox?
• VB.NET-BindingSource/DataGridView
• DatGridViewColumn.DisplayIndex property not setting the requested value.
• Refresh Binding
• Why are getters called so many times on data bound object properties ?
• Switching text direction (RightToLeft) in DataGridViewTextBoxCell
• Passing sp_executesql into table
• c# How to use ComboBox independent Value to determine What to Display in DatagridView?
• Databinding two ComboBoxes together