none
关于DataGridview控件中单元格合并的问题 RRS feed

  • 问题

  • 我想将DataGridView控件中的某几个单元格合并成一个单元格,其中有纵向合并的和横向合并。找了好多教程都不理想,请高手给指点一下。


    myriceme
    2011年2月2日 8:20

答案

  • Hi Lilin,

     

    不好意思,我来晚了。

    DGV控件中没有相关的方法或者属性来实现单元格的合并,但是你可以在DataGridView.CellPainting事件中Graphics.DrawLine方法和Graphics.DrawString方法实现。

     

    下面是垂直合并单元格的代码,你试试看:

     

    Imports System.Data.OleDb

     

    Public Class Form1

     

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

            Dim con As OleDbConnection = New OleDbConnection("Provider=Microsoft.jet.oledb.4.0;data source=D:\myDB.mdb")

            Dim cmd As OleDbCommand = New OleDbCommand("SELECT * FROM Users", con)

            con.Open()

            Dim myDA As OleDbDataAdapter = New OleDbDataAdapter(cmd)

            Dim myDataSet As DataSet = New DataSet()

            myDA.Fill(myDataSet, "MyTable")

            DataGridView1.DataSource = myDataSet.Tables("MyTable").DefaultView

            con.Close()

            con = Nothing

        End Sub

     

        'e.g. Vertically merge the same cells of the fourth column 

        Private Sub DataGridView1_CellPainting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting

     

            If e.ColumnIndex = 3 AndAlso e.RowIndex <> -1 Then

     

                Using gridBrush As Brush = New SolidBrush(Me.DataGridView1.GridColor), backColorBrush As Brush = New SolidBrush(e.CellStyle.BackColor)

     

                    Using gridLinePen As Pen = New Pen(gridBrush)

                        ' Clear cell 

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

     

                        ' Draw line (bottom border and right border of current cell) 

                        'If next row cell has different content, only draw bottom border line of current cell 

                        If e.RowIndex < DataGridView1.Rows.Count - 2 AndAlso DataGridView1.Rows(e.RowIndex + 1).Cells(e.ColumnIndex).Value.ToString() <> e.Value.ToString() Then

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

                        End If

     

                        ' Draw right border line of current cell 

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

     

                        ' draw/fill content in current cell, and fill only one cell of multiple same cells 

                        If Not e.Value Is Nothing Then

                            If e.RowIndex > 0 AndAlso DataGridView1.Rows(e.RowIndex - 1).Cells(e.ColumnIndex).Value.ToString() = e.Value.ToString() Then

                            Else

                                e.Graphics.DrawString(CType(e.Value, String), e.CellStyle.Font, Brushes.Black, e.CellBounds.X + 2, e.CellBounds.Y + 5, StringFormat.GenericDefault)

                            End If

                        End If

     

                        e.Handled = True

                    End Using

                End Using

            End If

        End Sub

     

    End Class

     

    横向合并单元格的两个列子:

    http://www.codeguru.com/forum/showthread.php?p=1537635#post1537635

    http://www.codeguru.com/forum/attachment.php?attachmentid=18792

     

    这两个例子都是用C#写的,但是你可以用工具转换一下:

    http://www.carlosag.net/Tools/CodeTranslator/

     

    希望上面的资料对你有帮助

    新年快乐


    Calvin Gao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年2月8日 8:07
    版主

全部回复

  • Hi Lilin,

     

    不好意思,我来晚了。

    DGV控件中没有相关的方法或者属性来实现单元格的合并,但是你可以在DataGridView.CellPainting事件中Graphics.DrawLine方法和Graphics.DrawString方法实现。

     

    下面是垂直合并单元格的代码,你试试看:

     

    Imports System.Data.OleDb

     

    Public Class Form1

     

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

            Dim con As OleDbConnection = New OleDbConnection("Provider=Microsoft.jet.oledb.4.0;data source=D:\myDB.mdb")

            Dim cmd As OleDbCommand = New OleDbCommand("SELECT * FROM Users", con)

            con.Open()

            Dim myDA As OleDbDataAdapter = New OleDbDataAdapter(cmd)

            Dim myDataSet As DataSet = New DataSet()

            myDA.Fill(myDataSet, "MyTable")

            DataGridView1.DataSource = myDataSet.Tables("MyTable").DefaultView

            con.Close()

            con = Nothing

        End Sub

     

        'e.g. Vertically merge the same cells of the fourth column 

        Private Sub DataGridView1_CellPainting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting

     

            If e.ColumnIndex = 3 AndAlso e.RowIndex <> -1 Then

     

                Using gridBrush As Brush = New SolidBrush(Me.DataGridView1.GridColor), backColorBrush As Brush = New SolidBrush(e.CellStyle.BackColor)

     

                    Using gridLinePen As Pen = New Pen(gridBrush)

                        ' Clear cell 

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

     

                        ' Draw line (bottom border and right border of current cell) 

                        'If next row cell has different content, only draw bottom border line of current cell 

                        If e.RowIndex < DataGridView1.Rows.Count - 2 AndAlso DataGridView1.Rows(e.RowIndex + 1).Cells(e.ColumnIndex).Value.ToString() <> e.Value.ToString() Then

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

                        End If

     

                        ' Draw right border line of current cell 

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

     

                        ' draw/fill content in current cell, and fill only one cell of multiple same cells 

                        If Not e.Value Is Nothing Then

                            If e.RowIndex > 0 AndAlso DataGridView1.Rows(e.RowIndex - 1).Cells(e.ColumnIndex).Value.ToString() = e.Value.ToString() Then

                            Else

                                e.Graphics.DrawString(CType(e.Value, String), e.CellStyle.Font, Brushes.Black, e.CellBounds.X + 2, e.CellBounds.Y + 5, StringFormat.GenericDefault)

                            End If

                        End If

     

                        e.Handled = True

                    End Using

                End Using

            End If

        End Sub

     

    End Class

     

    横向合并单元格的两个列子:

    http://www.codeguru.com/forum/showthread.php?p=1537635#post1537635

    http://www.codeguru.com/forum/attachment.php?attachmentid=18792

     

    这两个例子都是用C#写的,但是你可以用工具转换一下:

    http://www.carlosag.net/Tools/CodeTranslator/

     

    希望上面的资料对你有帮助

    新年快乐


    Calvin Gao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年2月8日 8:07
    版主
  • 感谢Calvin-MSFT版主的回复,您给的代码我还得消化一下,谢谢。<abbr class="affil" /><abbr class="affil" />


    myriceme
    2011年2月9日 8:57
  • You're welcome:)
    Calvin Gao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年2月9日 9:12
    版主
  • 感谢Calvin-Gao给予的帮助!!!

    我的程序界面实际上是一个用“DataGridView”控件做的表格模板,有5列7行,其中第一行的5个单元格合并成一个单元格(A1~E1),然后A2和A3单元格合并成一个单元格,A4和A5单元格合并成一个单元格,A6和A7单元格合并成一个单元格,其余单元格通过DataGridView1(x, y).Value赋值,最后将DataGridView打印出来。

    A1   B1   C1   D1   E1

    A2   B2   C2   D2   E2

    A3   B3   C3   D3   E3

    A4   B4   C4   D4   E4

    A5   B5   C5   D5   E5

    A6   B6   C6   D6   E6

    A7   B7   C7   D7   E7

    您给的代码和例子我都好好研究了一遍,但是我才学vb不久能力比较低,其中很多代码都没有读懂,麻烦您把以下代码的意思给我讲解一下:

     

    题1:DataGridView1_CellPainting(,)中的两个实参是什么值?

    问题2:如果合并成功如何给合并的单元格填写文字?

    问题3:合并单元格是一个什么原理,它的绘制原理是什么?

    谢谢!!!

     


    myriceme
    2011年2月10日 13:56
  • 你好,

     

    DataGridView1_CellPainting 是一个事件的处理:

    http://msdn.microsoft.com/zh-cn/library/2ccyd347.aspx

     

    关于CellPainting 事件:

    http://msdn.microsoft.com/zh-cn/library/system.windows.forms.datagridview.cellpainting.aspx

    怎样打印DGV,请看这个帖子中我的回复:

    http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/a026003a-295b-4867-923d-70f70c269982/

    希望对你有帮助 :-)


    Calvin Gao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年2月14日 3:27
    版主
  • 非常感谢!!我找了一个星期,最后还是您提供的方法实现了纵向合并的功能。

    2011年6月7日 10:54