vb.net中dataGridView的单元格的合并

对于下面的表格数据,我们经常会见到,

2009060100001100abc1sumisu
2008060100001120abc1yasio
2007060100001150def1toms
2005060100001190efg1arabama


但有时候我们希望将同一列中内容相同的单元格合并,变成下面这样:
2009060100001100abc1sumisu
20080601120yasio
20070601150deftoms
20050601190efgarabama

那么该如何实现呢?
在网上调查了很多方法,也请教了很多人,虽然有一些解决方法,但都不是最理想的。
偶尔下载到一个例子,很漂亮地实现了这个功能,不过是C#的,于是我花了不少时间,终于将她用VB.net实现了,在这里与各位分享。

Imports  System
Imports  System.Collections.Generic
Imports  System.ComponentModel
Imports  System.Data
Imports  System.Drawing
Imports  System.Drawing.Design
Imports  System.Text
Imports  System.Windows.Forms
Imports  System.Collections
Imports  System.Reflection
Imports  System.Runtime.InteropServices

Public   Class RowMergeView Class RowMergeView
    
Inherits DataGridView

    
Protected Overrides Sub OnCellPainting()Sub OnCellPainting(ByVal e As DataGridViewCellPaintingEventArgs)

        
If e.RowIndex > -1 And e.ColumnIndex > -1 Then
            DrawCell(e)
        
End If

    
End Sub


    
'/ <summary>
    '/ DrawCell
    '/ </summary>
    '/ <param name="e"></param>
    Private Sub DrawCell()Sub DrawCell(ByVal e As DataGridViewCellPaintingEventArgs)
        
If e.CellStyle.Alignment = DataGridViewContentAlignment.NotSet Then
            e.CellStyle.Alignment 
= DataGridViewContentAlignment.MiddleCenter
        
End If
        
Dim gridBrush As Brush = New SolidBrush(Me.GridColor)
        
'Dim backBrush As SolidBrush = New SolidBrush(e.CellStyle.BackColor)
        Dim backBrush As SolidBrush = New SolidBrush(Color.White)
        
Dim fontBrush As SolidBrush = New SolidBrush(e.CellStyle.ForeColor)
        
Dim cellwidth As Integer
        
Dim UpRows As Integer = 0
        
Dim DownRows As Integer = 0
        
Dim count As Integer = 0
        
If Me.MergeColumnNames.Contains(Me.Columns(e.ColumnIndex).Name) And e.RowIndex <> -1 Then
            cellwidth 
= e.CellBounds.Width
            
Dim gridLinePen As Pen = New Pen(gridBrush)
            
Dim curValue As String = CType(e.Value, String)
            
IIf(curValue Is Nothing"", e.Value.ToString().Trim())
            
Dim curSelected As String = CType(Me.CurrentRow.Cells(e.ColumnIndex).Value, String)
            
IIf(curSelected Is Nothing""Me.CurrentRow.Cells(e.ColumnIndex).Value.ToString().Trim())
            
'If Not String.IsNullOrEmpty(curValue) Then
            Dim i As Integer
            
For i = e.RowIndex To Me.Rows.Count - 1 Step i + 1
                
If Me.Rows(i).Cells(e.ColumnIndex).Value.ToString().Equals(curValue) Then

                    DownRows 
= DownRows + 1
                    
If e.RowIndex <> i Then
                        cellwidth 
= cellwidth
                        
IIf(cellwidth < Me.Rows(i).Cells(e.ColumnIndex).Size.Width, cellwidth, Me.Rows(i).Cells(e.ColumnIndex).Size.Width)
                    
End If
                
Else
                    
Exit For
                
End If
            
Next

            
Dim j As Integer
            
For j = e.RowIndex To 0 Step j - 1
                
If Me.Rows(j).Cells(e.ColumnIndex).Value.ToString().Equals(curValue) Then

                    UpRows 
= UpRows + 1
                    
If e.RowIndex <> j Then
                        cellwidth 
= cellwidth
                        
IIf(cellwidth < Me.Rows(j).Cells(e.ColumnIndex).Size.Width, cellwidth, Me.Rows(j).Cells(e.ColumnIndex).Size.Width)
                    
End If
                
Else
                    
Exit For
                
End If
            
Next

            count 
= DownRows + UpRows - 1
            
If count < 2 Then
                
Return
            
End If
            
'End If
            If Me.Rows(e.RowIndex).Selected Then
                backBrush.Color 
= e.CellStyle.SelectionBackColor
                fontBrush.Color 
= e.CellStyle.SelectionForeColor
            
End If

            e.Graphics.FillRectangle(backBrush, e.CellBounds)

            PaintingFont(e, cellwidth, UpRows, DownRows, count)
            
If DownRows = 1 Then
                e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom 
- 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1)
                count 
= 0
            
End If

            e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right 
- 1, e.CellBounds.Top, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1)

            e.Handled 
= True
        
End If
    
End Sub


    
'/ <summary>
    '/ PaintingFont
    '/ </summary>
    Private Sub PaintingFont()Sub PaintingFont(ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs, ByVal cellwidth As IntegerByVal UpRows As IntegerByVal DownRows As IntegerByVal count As Integer)
        
Dim fontBrush As SolidBrush = New SolidBrush(e.CellStyle.ForeColor)
        
Dim fontheight As Integer = CType(e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Height, Integer)
        
Dim fontwidth As Integer = CType(e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Width, Integer)
        
Dim cellheight As Integer = e.CellBounds.Height

        
If e.CellStyle.Alignment = DataGridViewContentAlignment.BottomCenter Then
            e.Graphics.DrawString(
CType(e.Value, String), e.CellStyle.Font, fontBrush, CType(e.CellBounds.X + (cellwidth - fontwidth) / 2Single), e.CellBounds.Y + cellheight * DownRows - fontheight)
        
ElseIf e.CellStyle.Alignment = DataGridViewContentAlignment.BottomLeft Then
            e.Graphics.DrawString(
CType(e.Value, String), e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y + cellheight * DownRows - fontheight)
        
ElseIf e.CellStyle.Alignment = DataGridViewContentAlignment.BottomRight Then
            e.Graphics.DrawString(
CType(e.Value, String), e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y + cellheight * DownRows - fontheight)
        
ElseIf e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter Then
            e.Graphics.DrawString(
CType(e.Value, String), e.CellStyle.Font, fontBrush, CType(e.CellBounds.X + (cellwidth - fontwidth) / 2Single), CType(e.CellBounds.Y - cellheight * (UpRows - 1+ (cellheight * count - fontheight) / 2Single))
        
ElseIf e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft Then
            e.Graphics.DrawString(
CType(e.Value, String), e.CellStyle.Font, fontBrush, e.CellBounds.X, CType(e.CellBounds.Y - cellheight * (UpRows - 1+ (cellheight * count - fontheight) / 2Single))
        
ElseIf e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleRight Then
            e.Graphics.DrawString(
CType(e.Value, String), e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, CType(e.CellBounds.Y - cellheight * (UpRows - 1+ (cellheight * count - fontheight) / 2Single))
        
ElseIf e.CellStyle.Alignment = DataGridViewContentAlignment.TopCenter Then
            e.Graphics.DrawString(
CType(e.Value, String), e.CellStyle.Font, fontBrush, e.CellBounds.X + CType((cellwidth - fontwidth) / 2Single), e.CellBounds.Y - cellheight * (UpRows - 1))
        
ElseIf e.CellStyle.Alignment = DataGridViewContentAlignment.TopLeft Then
            e.Graphics.DrawString(
CType(e.Value, String), e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y - cellheight * (UpRows - 1))
        
ElseIf e.CellStyle.Alignment = DataGridViewContentAlignment.TopRight Then
            e.Graphics.DrawString(
CType(e.Value, String), e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y - cellheight * (UpRows - 1))
        
Else
            e.Graphics.DrawString(
CType(e.Value, String), e.CellStyle.Font, fontBrush, e.CellBounds.X + CType((cellwidth - fontwidth) / 2Single), CType(e.CellBounds.Y - cellheight * (UpRows - 1+ (cellheight * count - fontheight) / 2Single))
        
End If
    
End Sub


    
'/ <summary>
    '/ MergeColumnNames
    '/ </summary>
    Public Property MergeColumnNames()Property MergeColumnNames() As List(Of String)
        
Get
            
Return _mergecolumnname
        
End Get
        
Set(ByVal Value As List(Of String))
            _mergecolumnname 
= Value
        
End Set
    
End Property

    
Private _mergecolumnname As List(Of String= New List(Of String)()

End Class


Imports  System
Imports  System.Collections.Generic
Imports  System.ComponentModel
Imports  System.Data
Imports  System.Drawing
Imports  System.Text
Imports  System.Windows.Forms


Public   Class Form1 Class Form1

    
Public Sub New()Sub New()
        InitializeComponent()
        
Dim dt As DataTable = New DataTable()
        
Dim i As Integer
        dt.Columns.Add(
"1")
        dt.Columns.Add(
"2")
        dt.Columns.Add(
"3")
        dt.Columns.Add(
"4")
        dt.Columns.Add(
"5")
        dt.Columns.Add(
"6")
        dt.Rows.Add(
"20090601""00001""100""abc""1""sumisu")
        dt.Rows.Add(
"20080601""00001""120""abc""1""yasio")
        dt.Rows.Add(
"20070601""00001""150""def""1""toms")
        dt.Rows.Add(
"20050601""00001""190""efg""1""arabama")
        
Me.rowMergeView1.DataSource = dt
        
Me.rowMergeView1.ColumnHeadersHeight = 20
        
Me.rowMergeView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing
        
For i = 1 To dt.Columns.Count
            
Me.rowMergeView1.MergeColumnNames.Add("Column" & i)
        
Next
    
End Sub

End Class


< Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated() >  _
Partial 
Class Form1 Class Form1
    
Inherits System.Windows.Forms.Form

    
'フォームがコンポーネントの一覧をクリーンアップするために dispose をオーバーライドします。
    <System.Diagnostics.DebuggerNonUserCode()> _
    
Protected Overrides Sub Dispose()Sub Dispose(ByVal disposing As Boolean)
        
Try
            
If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            
End If
        
Finally
            
MyBase.Dispose(disposing)
        
End Try
    
End Sub


    
'Windows フォーム デザイナで必要です。
    Private components As System.ComponentModel.IContainer

    
'メモ: 以下のプロシージャは Windows フォーム デザイナで必要です。
    'Windows フォーム デザイナを使用して変更できます。  
    'コード エディタを使って変更しないでください。
    <System.Diagnostics.DebuggerStepThrough()> _
    
Private Sub InitializeComponent()Sub InitializeComponent()
        
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(Form1))
        
Me.Panel1 = New System.Windows.Forms.Panel
        
Me.Button1 = New System.Windows.Forms.Button
        
Me.rowMergeView1 = New testMearge.RowMergeView
        
Me.Column1 = New System.Windows.Forms.DataGridViewTextBoxColumn
        
Me.Column2 = New System.Windows.Forms.DataGridViewTextBoxColumn
        
Me.Column3 = New System.Windows.Forms.DataGridViewTextBoxColumn
        
Me.Column4 = New System.Windows.Forms.DataGridViewTextBoxColumn
        
Me.Column5 = New System.Windows.Forms.DataGridViewTextBoxColumn
        
Me.Column6 = New System.Windows.Forms.DataGridViewTextBoxColumn
        
Me.Panel1.SuspendLayout()
        
CType(Me.rowMergeView1, System.ComponentModel.ISupportInitialize).BeginInit()
        
Me.SuspendLayout()
        
'
        'Panel1
        '
        Me.Panel1.Controls.Add(Me.Button1)
        
Me.Panel1.Dock = System.Windows.Forms.DockStyle.Bottom
        
Me.Panel1.Location = New System.Drawing.Point(0312)
        
Me.Panel1.Name = "Panel1"
        
Me.Panel1.Size = New System.Drawing.Size(59531)
        
Me.Panel1.TabIndex = 1
        
'
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(4995)
        
Me.Button1.Name = "Button1"
        
Me.Button1.Size = New System.Drawing.Size(7523)
        
Me.Button1.TabIndex = 0
        
Me.Button1.Text = "Button1"
        
Me.Button1.UseVisualStyleBackColor = True
        
'
        'rowMergeView1
        '
        Me.rowMergeView1.AllowUserToAddRows = False
        
Me.rowMergeView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill
        
Me.rowMergeView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
        
Me.rowMergeView1.Columns.AddRange(New System.Windows.Forms.DataGridViewColumn() {Me.Column1, Me.Column2, Me.Column3, Me.Column4, Me.Column5, Me.Column6})
        
Me.rowMergeView1.Dock = System.Windows.Forms.DockStyle.Fill
        
Me.rowMergeView1.Location = New System.Drawing.Point(00)
        
Me.rowMergeView1.MergeColumnNames = CType(resources.GetObject("rowMergeView1.MergeColumnNames"), System.Collections.Generic.List(Of String))
        
Me.rowMergeView1.Name = "rowMergeView1"
        
Me.rowMergeView1.RowTemplate.Height = 21
        
Me.rowMergeView1.Size = New System.Drawing.Size(595343)
        
Me.rowMergeView1.TabIndex = 0
        
'
        'Column1
        '
        Me.Column1.DataPropertyName = "1"
        
Me.Column1.HeaderText = "日期"
        
Me.Column1.Name = "Column1"
        
'
        'Column2
        '
        Me.Column2.DataPropertyName = "2"
        
Me.Column2.HeaderText = "代码"
        
Me.Column2.Name = "Column2"
        
'
        'Column3
        '
        Me.Column3.DataPropertyName = "3"
        
Me.Column3.HeaderText = "价格"
        
Me.Column3.Name = "Column3"
        
'
        'Column4
        '
        Me.Column4.DataPropertyName = "4"
        
Me.Column4.HeaderText = "备注"
        
Me.Column4.Name = "Column4"
        
'
        'Column5
        '
        Me.Column5.DataPropertyName = "5"
        
Me.Column5.HeaderText = "标志"
        
Me.Column5.Name = "Column5"
        
'
        'Column6
        '
        Me.Column6.DataPropertyName = "6"
        
Me.Column6.HeaderText = "更新者"
        
Me.Column6.Name = "Column6"
        
'
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 12.0!)
        
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        
Me.ClientSize = New System.Drawing.Size(595343)
        
Me.Controls.Add(Me.Panel1)
        
Me.Controls.Add(Me.rowMergeView1)
        
Me.Name = "Form1"
        
Me.Text = "Form1"
        
Me.Panel1.ResumeLayout(False)
        
CType(Me.rowMergeView1, System.ComponentModel.ISupportInitialize).EndInit()
        
Me.ResumeLayout(False)

    
End Sub

    
Friend WithEvents rowMergeView1 As RowMergeView
    
Friend WithEvents Panel1 As System.Windows.Forms.Panel
    
Friend WithEvents Button1 As System.Windows.Forms.Button
    
Friend WithEvents Column1 As System.Windows.Forms.DataGridViewTextBoxColumn
    
Friend WithEvents Column2 As System.Windows.Forms.DataGridViewTextBoxColumn
    
Friend WithEvents Column3 As System.Windows.Forms.DataGridViewTextBoxColumn
    
Friend WithEvents Column4 As System.Windows.Forms.DataGridViewTextBoxColumn
    
Friend WithEvents Column5 As System.Windows.Forms.DataGridViewTextBoxColumn
    
Friend WithEvents Column6 As System.Windows.Forms.DataGridViewTextBoxColumn

End Class


运行结果如下:
 
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值