DataGridView MultiRowCellMergedHeader   otázka

VB.NET, Komponenty, WinForms

Jak lze vytvořit v datagridview další řádek záhlaví sloupců?

Příklad pro představu: třeba naplnit sloupce názvy měsíců

a nad nimi v horním záhlaví zobrazit číslo čtvtletí měsíce

jako sloučenou buňku vždy pro dané tři měsíce

Vydat se cestou vlastního vykreslování v události Paint?

Problém mám s vykreslením části sloučené buňky s částí

textu s daným zarovnáním záhlaví při posouvání sloupců

vodorovným posuvníkem:

Např. aktuálně bude zobrazena část sloučeného záhlaví

pro měsíce leden až březem s textem "1.čtvtletí", text

se zarovnáním na střed a viditelná bude část sloupce únor

Nevíte, jak si poradit s vykreslením potřebné části textu?

Jakým způsobem to má datagridview pořešené, existují nějaké

metody, které lze obdobně použít? Jak na to s DrawString?

Není možnost si vykreslit celé další záhlaví samostatně?

Nebo si ulehčit útrapy s vlastním vykreslováním a synchronizovat

nějaký např. panel s labely se záhlavími sloupců datagridview?

Neřešil,prosím,již někdo z Vás něco podobného pro svoji potřebu?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nastudujte si řádně komponentu DataGridView,podporuej vlastní napsání obsahu nebo i vlastnosti pro definici záhlaví

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Dík za reakci, ale asi stále přehlížím vlastnost,

která by umožnila zadání dalšího (druhého) řádku

záhlaví navíc s možností slučovat jeho buňky...

Máte snad na mysli něco konkrétního?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nemám moc zkušeností s grafics a vlastním vykreslováním,

přesto se pokusím o příklad, povede-li se mi celé vložit.

Jedná se jakýsi o kvartální a týdenní přehled evidence

(zde např. zneužívání židlí pro pana faráře).

Veškeré nápady, jak na to jít správně jsou vítány.

Public Class Form1
    Dim tc As TabControl
    Private Sub Form1_Load(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.Load

        Me.Text = "MultiHeaderDataGridView TestForm"
        tc = New TabControl
        With tc
            AddHandler .DrawItem, AddressOf tc_DrawItem
            .ItemSize = New Size(100, 25)
            .TabPages.Add("1", "Quarters")
            .TabPages.Add("2", "Weeks Of Year")
            .Dock = DockStyle.Fill
            .Alignment = System.Windows.Forms.TabAlignment.Left
            .SizeMode = TabSizeMode.Fixed
            .DrawMode = TabDrawMode.OwnerDrawFixed
        End With

        Dim dg1 As New MultiHeaderDataGridView
        Dim dg2 As New MultiHeaderDataGridView
        Dim dt As New DataTable
        With dt
            .Columns.Add("F1", Type.GetType("System.Int32"))
            .Columns.Add("F2", Type.GetType("System.String"))
            .Columns.Add("F3", Type.GetType("System.String"))
            .Columns.Add("1", Type.GetType("System.Int32"))
            .Columns.Add("2", Type.GetType("System.Int32"))
            .Columns.Add("3", Type.GetType("System.Int32"))
            .Columns.Add(FormatDateTime(Now.Date, DateFormat.ShortDate), _
                Type.GetType("System.Int32"))
            .Rows.Add(1, "Josef", "Škopek", 1, 2, 3, 0)
            .Rows.Add(2, "Venca", "Konopník", 2, 3, 3, 1)
            .Rows.Add(3, "Jirka", "Škopek", 2, 2, 3, 2)
            .Rows.Add(4, "Gábina", "Tejfarová", 3, 4, 3, 3)
            .Rows.Add(5, "Blažena", "Škopková", 4, 2, 3, 4)
            .Rows.Add(6, "Šimon", "Plánička", 7, 2, 3, 5)
            .Rows.Add(7, "Josef", "Tlustý", 9, 2, 3, 6)
            .Rows.Add(8, "Emílie", "Kelišová", 7, 2, 5, 7)
            .Rows.Add(9, "Pavel", "Konopník", 8, 6, 3, 8)
            .Rows.Add(10, "Antonie", "Konopníková", 1, 2, 3, 9)
        End With

        Dim y As Integer = Now.Year

        With dg1
            .AutoGenerateColumns = False
            .BorderStyle = BorderStyle.FixedSingle
            .StandardTab = True
            .ColumnHeadersHeight = .ColumnHeadersHeight * 2
            .AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
            .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
            .Dock = DockStyle.Fill
            .Columns.Add("F1", "č.")
            .Columns("F1").DataPropertyName = "F1"
            .Columns("F1").DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
            .Columns.Add("F2", "jméno")
            .Columns("F2").DataPropertyName = "F2"
            .Columns.Add("F3", "příjmení")
            .Columns("F3").DataPropertyName = "F3"
            .Columns("F3").Frozen = True

            For i As Integer = 1 To 12
                .Columns.Add(i.ToString, MonthName(i).ToString)
                .Columns(.Columns.Count - 1).SortMode = DataGridViewColumnSortMode.NotSortable
                .Columns(.Columns.Count - 1).DataPropertyName = i.ToString
                .Columns(.Columns.Count - 1).DefaultCellStyle.Alignment = _
                    DataGridViewContentAlignment.MiddleRight
                Dim q As Integer = DatePart(DateInterval.Quarter, New Date(y, i, 1))
                If .MultiHeaders.Count = 0 Then .MultiHeaders.Add(New MultiHeader(q.ToString, _
                    .Columns.Count - 1, .Columns.Count - 1))
                If .MultiHeaders(.MultiHeaders.Count - 1).Text = q.ToString Then
                    Dim mh As MultiHeader = .MultiHeaders(.MultiHeaders.Count - 1)
                    mh.LastColumnIndex = .Columns.Count - 1
                Else
                    .MultiHeaders.Add(New MultiHeader(q.ToString, _
                        .Columns.Count - 1, .Columns.Count - 1))
                End If
                .Columns(.Columns.Count - 1).Tag = .MultiHeaders.Count - 1
                With .MultiHeaders(.MultiHeaders.Count - 1)
                    .BackColor = dg1.ColumnHeadersDefaultCellStyle.BackColor
                    Select Case q
                        Case 1
                            .BackColor = Color.LightCoral
                        Case 2
                            .BackColor = Color.Lavender
                        Case 3
                            .BackColor = Color.LightSeaGreen
                        Case 4
                            .BackColor = Color.LightSalmon
                    End Select
                End With
            Next
            .DataSource = dt
        End With

        With dg2
            .AutoGenerateColumns = False
            .BorderStyle = BorderStyle.FixedSingle
            .StandardTab = True
            .ColumnHeadersHeight = .ColumnHeadersHeight * 2
            .AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
            .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
            .Dock = DockStyle.Fill
            .Columns.Add("F1", "č.")
            .Columns("F1").DataPropertyName = "F1"
            .Columns("F1").DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
            .Columns.Add("F2", "jméno")
            .Columns("F2").DataPropertyName = "F2"
            .Columns.Add("F3", "příjmení")
            .Columns("F3").DataPropertyName = "F3"
            .Columns("F3").Frozen = True

            For m As Integer = 1 To 12
                For i As Integer = 1 To Date.DaysInMonth(y, m)
                    Dim d As Date = New Date(y, m, i)
                    .Columns.Add(FormatDateTime(d, DateFormat.ShortDate), i.ToString)
                    .Columns(.Columns.Count - 1).DataPropertyName = FormatDateTime(d, DateFormat.ShortDate)
                    .Columns(.Columns.Count - 1).SortMode = DataGridViewColumnSortMode.NotSortable
                    Dim w As Integer = DatePart(DateInterval.WeekOfYear, New Date(y, m, i), _
                        FirstDayOfWeek.Monday, FirstWeekOfYear.FirstFourDays)

                    .Columns(.Columns.Count - 1).HeaderCell.Tag = Weekday(d, FirstDayOfWeek.Monday)
                    If Weekday(d, FirstDayOfWeek.Monday) = 6 Then
                        .Columns(.Columns.Count - 1).HeaderCell.Style.BackColor = Color.Green
                    ElseIf Weekday(d, FirstDayOfWeek.Monday) = 7 Then
                        .Columns(.Columns.Count - 1).HeaderCell.Style.BackColor = Color.Red
                    End If
                    If .MultiHeaders.Count = 0 Then .MultiHeaders.Add(New MultiHeader(w.ToString, _
                        .Columns.Count - 1, .Columns.Count - 1))
                    If .MultiHeaders(.MultiHeaders.Count - 1).Text = w.ToString Then
                        Dim mh As MultiHeader = .MultiHeaders(.MultiHeaders.Count - 1)
                        mh.LastColumnIndex = .Columns.Count - 1
                    Else
                        .MultiHeaders.Add(New MultiHeader(w.ToString, _
                            .Columns.Count - 1, .Columns.Count - 1))
                    End If
                    .Columns(d).Tag = .MultiHeaders.Count - 1
                Next
            Next
            .DataSource = dt
        End With
        Me.Controls.Add(tc)
        tc.TabPages("1").Controls.Add(dg1)
        tc.TabPages("2").Controls.Add(dg2)
    End Sub

    Private Sub tc_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs)
        Dim _TextBrush As Brush = New System.Drawing.SolidBrush(SystemColors.WindowText)
        ' get the item from the collection 
        Dim _TabPage As TabPage = tc.TabPages(e.Index)
        ' get the real bounds for the tab rectangle
        Dim _TabBounds As RectangleF = tc.GetTabRect(e.Index)

        Dim _TabFont As Font
        If (e.State = DrawItemState.Selected) Then
            _TabFont = New Font(tc.Font, FontStyle.Bold)
            e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLightLight), e.Bounds)
        Else
            _TabFont = New Font(tc.Font, FontStyle.Regular)
        End If
        If e.State = DrawItemState.Focus Then e.DrawFocusRectangle()
        ' draw string vertically and center the text
        Dim _StringFlags As New StringFormat()
        _StringFlags.Alignment = StringAlignment.Center
        _StringFlags.LineAlignment = StringAlignment.Center
        _StringFlags.FormatFlags = StringFormatFlags.DirectionVertical
        e.Graphics.DrawString(_TabPage.Text, _TabFont, _TextBrush, _TabBounds, _StringFlags)
        _TabFont.Dispose()
        _TextBrush.Dispose()
        _StringFlags.Dispose()
    End Sub

    Partial Class MultiHeader
        Public Text As String
        Public BackColor As Color
        Public FirstColumnIndex As Integer
        Public LastColumnIndex As Integer

        Sub New(ByVal text As String, ByVal firstColIndex As Integer, ByVal lastColIndex As Integer)
            Me.Text = text
            Me.FirstColumnIndex = firstColIndex
            Me.LastColumnIndex = lastColIndex
            Me.BackColor = Color.Empty
        End Sub
    End Class

    Partial Class MultiHeaderDataGridView
        Inherits DataGridView
        Public MultiHeaders As New List(Of MultiHeader)(0)


        Private Sub MultiHeaderDataGridView_CellPainting(ByVal sender As Object, _
            ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles Me.CellPainting

            Dim SelectedMultiHeaderHighlightColor As Color = Color.FromArgb(255, SystemColors.ControlDarkDark)
            If e.RowIndex = -1 Then
                'bottom line
                With e.CellBounds
                    e.Graphics.DrawLine(New Pen(Me.GridColor), _
                        .Left, .Y + .Height - 1, .Right - 1, .Y + .Height - 1)
                End With
                'bottom half rect
                Dim r As Rectangle
                With e.CellBounds
                    r = New Rectangle(.X, .Y + .Height / 2, .Width, .Height / 2)
                End With
                'cellbounds height less one
                Dim rc As Rectangle
                With e.CellBounds
                    rc = New Rectangle(.X, .Y, .Width, .Height - 1)
                End With
                If e.ColumnIndex >= 0 Then
                    'background
                    e.Graphics.FillRectangle(New SolidBrush(Me.ColumnHeadersDefaultCellStyle.BackColor), rc)
                    If Me.Columns(e.ColumnIndex).Tag Is Nothing Then
                        With e.CellBounds
                            If e.ColumnIndex = Me.CurrentCell.ColumnIndex Then
                                Dim clr1, clr2 As System.Drawing.Color
                                clr1 = System.Drawing.SystemColors.Highlight
                                clr2 = Me.Columns(e.ColumnIndex).HeaderCell.Style.BackColor
                                Dim brush As New System.Drawing.Drawing2D.LinearGradientBrush( _
                                     e.CellBounds, clr1, clr2, System.Drawing.Drawing2D.LinearGradientMode.Vertical)
                                e.Graphics.FillRectangle(brush, .X, .Y, .Width - 1, .Height - 1)
                            End If
                            e.Graphics.DrawLine(New Pen(Me.GridColor), .Right - 1, .Y, .Right - 1, .Y + .Height)
                        End With
                    Else
                        If e.ColumnIndex = Me.CurrentCell.ColumnIndex Then
                            Dim clr1, clr2 As System.Drawing.Color
                            clr1 = System.Drawing.SystemColors.Highlight
                            clr2 = Me.Columns(e.ColumnIndex).HeaderCell.Style.BackColor
                            Dim brush As New System.Drawing.Drawing2D.LinearGradientBrush( _
                                 r, clr1, clr2, System.Drawing.Drawing2D.LinearGradientMode.Vertical)
                            e.Graphics.FillRectangle(brush, r.X, r.Y, r.Width, r.Height - 1)
                        Else
                            With Me.Columns(e.ColumnIndex).HeaderCell
                                If Not .Tag Is Nothing Then
                                    If .Tag = 6 Or .Tag = 7 Then
                                        Dim clr1, clr2 As System.Drawing.Color
                                        clr1 = Me.Columns(e.ColumnIndex).HeaderCell.Style.BackColor
                                        clr2 = Color.FromArgb(220, SystemColors.Window)
                                        Dim brush As New System.Drawing.Drawing2D.LinearGradientBrush( _
                                             New Rectangle(0, 0, e.CellBounds.Width, e.CellBounds.Height / 2), _
                                             clr1, clr2, System.Drawing.Drawing2D.LinearGradientMode.Vertical)
                                        e.Graphics.FillRectangle(brush, r.X, r.Y, r.Width, r.Height - 1)
                                    End If
                                End If
                            End With
                        End If

                        If MultiHeaders(Me.Columns(e.ColumnIndex).Tag).BackColor <> Color.Empty Then
                            Dim rt As Rectangle
                            With e.CellBounds
                                rt = New Rectangle(.X, .Y, .Width, .Height / 2)
                            End With
                            e.Graphics.FillRectangle(New SolidBrush(MultiHeaders(Me.Columns(e.ColumnIndex).Tag).BackColor), rt)
                        End If

                        Dim MultiHeaderSelected As Boolean
                        If Not Me.Columns(Me.CurrentCell.ColumnIndex).Tag Is Nothing Then
                            Dim p As Pen = New Pen(SelectedMultiHeaderHighlightColor)
                            With e.CellBounds
                                If MultiHeaders(Me.Columns(Me.CurrentCell.ColumnIndex).Tag).LastColumnIndex = e.ColumnIndex Then
                                    'draw right border of selected multiheader
                                    e.Graphics.DrawLine(p, .Right - 1, .Y, .Right - 1, .Bottom)
                                    MultiHeaderSelected = True
                                End If
                                If MultiHeaders(Me.Columns(Me.CurrentCell.ColumnIndex).Tag).FirstColumnIndex = e.ColumnIndex Then
                                    'draw left border of selected multiheader
                                    e.Graphics.DrawLine(p, .Left - 1, .Y, .Left - 1, .Bottom)
                                    MultiHeaderSelected = True
                                End If
                            End With
                            p.Dispose()
                        End If

                        If Not MultiHeaderSelected Then
                            If MultiHeaders(Me.Columns(e.ColumnIndex).Tag).LastColumnIndex = e.ColumnIndex Then
                                'if selected not drawn again
                                With e.CellBounds
                                    e.Graphics.DrawLine(New Pen(Me.GridColor), .Right - 1, .Y, .Right - 1, .Bottom)
                                End With
                            Else
                                e.Graphics.DrawLine(New Pen(Me.GridColor), r.Right - 1, r.Y, r.Right - 1, r.Y + r.Height)
                            End If
                        End If

                        e.Graphics.DrawLine(New Pen(Me.GridColor), r.Left, r.Y, r.Right - 1, r.Y)
                    End If 'tag is or not nothing
                Else
                    'corner cell background
                    e.Graphics.FillRectangle(New SolidBrush(Me.ColumnHeadersDefaultCellStyle.BackColor), rc)
                    With rc
                        'corner cell right border
                        e.Graphics.DrawLine(New Pen(Me.GridColor), .Right - 1, .Y, .Right - 1, .Y + .Height)
                    End With
                End If

                'draw headercell text
                If Not e.Value Is Nothing Then
                    With Me.ColumnHeadersDefaultCellStyle
                        Dim sf As New StringFormat
                        sf.Alignment = StringAlignment.Center
                        sf.LineAlignment = StringAlignment.Center
                        sf.FormatFlags = StringFormatFlags.NoWrap

                        sf.HotkeyPrefix = Drawing.Text.HotkeyPrefix.None
                        sf.Trimming = StringTrimming.None
                        Dim fs As FontStyle = FontStyle.Regular
                        If e.ColumnIndex = Me.CurrentCell.ColumnIndex Then _
                            fs = FontStyle.Bold
                        If Me.Columns(e.ColumnIndex).Tag Is Nothing Then
                            e.Graphics.DrawString(e.Value.ToString, New Font(.Font, fs), New SolidBrush(.ForeColor), rc, sf)
                        Else
                            e.Graphics.DrawString(e.Value.ToString, New Font(.Font, fs), New SolidBrush(.ForeColor), r, sf)
                        End If
                        sf.Dispose()
                    End With
                    Dim dte As Date
                    If Date.TryParse(Me.Columns(e.ColumnIndex).Name, dte) Then
                        If Now.Date = dte Then
                            Dim ElipseColor As Color = Me.Columns(e.ColumnIndex).HeaderCell.Style.BackColor
                            If e.ColumnIndex = Me.CurrentCell.ColumnIndex Then _
                                ElipseColor = SystemColors.Highlight
                            If ElipseColor = Color.Empty Then
                                ElipseColor = Me.ColumnHeadersDefaultCellStyle.ForeColor
                            Else
                                With ElipseColor
                                    ElipseColor = _
                                        Color.FromArgb(255 - CInt(.R), 255 - CInt(.G), 255 - CInt(.B))
                                End With
                            End If
                            With r
                                e.Graphics.DrawEllipse(New Pen(ElipseColor), _
                                    New Rectangle(.X + 1, .Y + 2, .Width - 4, .Height - 5))
                            End With
                        End If
                    End If
                End If
                e.Handled = True
            Else
                'no header cell
                If e.ColumnIndex >= 0 Then
                    Dim bHalf As Boolean = False
                    e.PaintBackground(e.ClipBounds, False)

                    Dim clr1 As System.Drawing.Color, clr2 As System.Drawing.Color = Me.DefaultCellStyle.BackColor
                    If e.ColumnIndex = Me.CurrentCell.ColumnIndex Then
                        clr1 = System.Drawing.SystemColors.Highlight
                    ElseIf e.ColumnIndex < Me.Columns.GetColumnCount(DataGridViewElementStates.Frozen) _
                                                    And e.RowIndex = Me.CurrentCell.RowIndex Then
                        clr1 = System.Drawing.SystemColors.Highlight
                    Else
                        clr1 = SystemColors.Window
                    End If

                    With Me.Columns(e.ColumnIndex).HeaderCell
                        If Not .Tag Is Nothing Then
                            Select Case .Tag
                                Case 6, 7
                                    clr2 = Color.FromArgb(50, .Style.BackColor)
                                Case Else
                                    clr2 = Me.DefaultCellStyle.BackColor
                            End Select
                        Else
                            If Me.Columns(e.ColumnIndex).Frozen Then clr2 = Color.FromKnownColor(KnownColor.Control)
                        End If
                    End With

                    Dim brush As New System.Drawing.Drawing2D.LinearGradientBrush( _
                        e.CellBounds, clr1, clr2, System.Drawing.Drawing2D.LinearGradientMode.Vertical)

                    
                    If e.ColumnIndex < Me.Columns.GetColumnCount(DataGridViewElementStates.Frozen) _
                        And e.RowIndex = Me.CurrentCell.RowIndex Then
                        e.Graphics.FillRectangle(brush, e.CellBounds)
                    Else
                        e.Graphics.FillRectangle(New SolidBrush(clr2), e.CellBounds)
                    End If

                    If e.RowIndex = Me.CurrentCell.RowIndex And e.ColumnIndex = Me.CurrentCell.ColumnIndex Then
                        e.Graphics.FillRectangle(brush, e.CellBounds)
                        'draw inverse color border selected cell
                        Dim inverse As Color = IIf(clr2 = Me.DefaultCellStyle.BackColor, SystemColors.Highlight, clr2)
                        With inverse
                            inverse = _
                                Color.FromArgb(255 - CInt(.R), 255 - CInt(.G), 255 - CInt(.B))
                            With e.CellBounds
                                e.Graphics.DrawRectangle(New Pen(inverse, 2), .X, .Y, .Width - 2, .Height - 2)
                            End With
                        End With
                    End If

                    e.PaintContent(e.CellBounds)
                    e.Paint(e.CellBounds, DataGridViewPaintParts.Border)
                    'left and right border of selected multiheader
                    If Not Me.Columns(Me.CurrentCell.ColumnIndex).Tag Is Nothing Then
                        Dim p As Pen = New Pen(SelectedMultiHeaderHighlightColor)
                        With e.CellBounds
                            If MultiHeaders(Me.Columns(Me.CurrentCell.ColumnIndex).Tag).LastColumnIndex = e.ColumnIndex Then
                                e.Graphics.DrawLine(p, .Right - 1, .Y, .Right - 1, .Bottom)
                            End If
                            If MultiHeaders(Me.Columns(Me.CurrentCell.ColumnIndex).Tag).FirstColumnIndex = e.ColumnIndex Then
                                e.Graphics.DrawLine(p, .Left - 1, .Y, .Left - 1, .Bottom)
                            End If
                        End With
                        p.Dispose()
                    End If
                    e.Handled = True
            End If
            End If
        End Sub

        Private Sub MultiHeaderDataGridView_ColumnWidthChanged(ByVal sender As Object, _
            ByVal e As System.Windows.Forms.DataGridViewColumnEventArgs) Handles Me.ColumnWidthChanged
            Me.Invalidate()
        End Sub

        Private Sub MultiHeaderDataGridView_MouseMove(ByVal sender As Object, _
            ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
            Dim mhParent As Integer
            Dim hti As HitTestInfo = Me.HitTest(e.X, e.Y)
            If hti Is Nothing Then Exit Sub
            If hti.ColumnIndex >= 0 And e.Y <= Me.ColumnHeadersHeight Then
                If Integer.TryParse(Me.Columns(hti.ColumnIndex).Tag, mhParent) Then
                    Dim s As String
                    If e.Y < Me.ColumnHeadersHeight / 2 Then
                        s = String.Format("{0} - {1}", _
                        Me.Columns(MultiHeaders(mhParent).FirstColumnIndex).Name, _
                        Me.Columns(MultiHeaders(mhParent).LastColumnIndex).Name)
                    Else
                        s = Me.Columns(hti.ColumnIndex).Name
                    End If
                    Me.Columns(hti.ColumnIndex).HeaderCell.ToolTipText = s
                End If
            End If
        End Sub
        Private Sub MultiHeaderDataGridView_Paint(ByVal sender As Object, _
            ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
            Dim al As New ArrayList()
            Dim LastDisplayedScrollingColumnIndex As Integer = Me.FirstDisplayedScrollingColumnIndex _
                + Me.DisplayedColumnCount(True) - 1 - Me.Columns.GetColumnCount(DataGridViewElementStates.Frozen)
            'get array list of visible multiheaders
            For i As Integer = Me.FirstDisplayedScrollingColumnIndex To LastDisplayedScrollingColumnIndex
                If Not Me.Columns(i).Tag Is Nothing Then
                    If Not al.Contains(Me.Columns(i).Tag) Then
                        al.Add(Me.Columns(i).Tag)
                    End If
                End If
            Next
            Dim sf As New StringFormat
            With sf
                .Alignment = StringAlignment.Center
                .LineAlignment = StringAlignment.Center
            End With
            Dim sb As SolidBrush = New SolidBrush(Me.ColumnHeadersDefaultCellStyle.ForeColor)

            For Each i As Integer In al
                ''fci=FirstMultiHeaderVisibleColumnIndex
                Dim fci As Integer = IIf(MultiHeaders(i).FirstColumnIndex < Me.FirstDisplayedScrollingColumnIndex, _
                    Me.FirstDisplayedScrollingColumnIndex, MultiHeaders(i).FirstColumnIndex)
                ''lci=LastMultiHeaderVisibleColumnIndex
                Dim lci As Integer = IIf(MultiHeaders(i).LastColumnIndex > LastDisplayedScrollingColumnIndex, _
                    LastDisplayedScrollingColumnIndex, MultiHeaders(i).LastColumnIndex)
                ''rf=FirstMultiHeaderVisibleColumnRectangle rl=LastMultiHeaderVisibleColumnRectangle 
                Dim rf As Rectangle = Me.GetColumnDisplayRectangle(fci, True)
                Dim rl As Rectangle = Me.GetColumnDisplayRectangle(lci, True)
                ''rh = CurrentMultiHeaderVisibleRectangle
                Dim rh As Rectangle = New Rectangle(rf.X, rf.Y, rl.X + rl.Width - rf.X - 1, Me.ColumnHeadersHeight / 2)

                Dim MultiHeaderFirstColumnInvisibleLeft = rf.X + rf.Width
                For j As Integer = MultiHeaders(i).FirstColumnIndex To fci
                    MultiHeaderFirstColumnInvisibleLeft = MultiHeaderFirstColumnInvisibleLeft - Me.Columns(fci).Width
                Next

                Dim FirstDisplayedScrollingMultiHeaderHiddenWidth As Integer = rh.X - MultiHeaderFirstColumnInvisibleLeft

                Dim fs As FontStyle = FontStyle.Regular

                Dim MultiHeaderFullWidth As Integer = 0
                For j As Integer = MultiHeaders(i).FirstColumnIndex To MultiHeaders(i).LastColumnIndex
                    MultiHeaderFullWidth = MultiHeaderFullWidth + Me.Columns(j).Width
                    If Me.CurrentCell.ColumnIndex = j Then _
                        fs = FontStyle.Bold
                Next

                Dim bmp As Bitmap = New Bitmap(MultiHeaderFullWidth, rh.Height, e.Graphics)
                Using g As Graphics = Graphics.FromImage(bmp)
                    g.Clear(Color.Transparent) 'Me.ColumnHeadersDefaultCellStyle.BackColor
                    ''rl= FullMultiHeaderRectangle
                    rl = New Rectangle(0, 0, MultiHeaderFullWidth, rh.Height)
                    ''draw centered string to rectangle
                    g.DrawString(MultiHeaders(i).Text, New Font(Me.ColumnHeadersDefaultCellStyle.Font, fs), sb, rl, sf)
                    ''all or part of multiheader - full or partially visible
                    rf = New Rectangle(FirstDisplayedScrollingMultiHeaderHiddenWidth, 0, rh.Width, bmp.Height)
                    ''draw bitmap to datagridview multiheader
                    e.Graphics.DrawImage(bmp, rh, rf, GraphicsUnit.Pixel)
                End Using
                bmp.Dispose()
            Next
            sf.Dispose()
            sb.Dispose()
        End Sub

        Private Sub MultiHeaderDataGridView_Scroll(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles Me.Scroll
            If e.ScrollOrientation = ScrollOrientation.HorizontalScroll Then
                Me.Invalidate()
            End If
        End Sub

        Private Sub MultiHeaderDataGridView_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SelectionChanged
            Static pt As Point
            If Not pt = Point.Empty Then
                If Me.CurrentCellAddress.X = pt.X Then
                    Dim r As Rectangle = New Rectangle(0, Me.ColumnHeadersHeight, Me.ClientRectangle.Width, Me.ClientRectangle.Height)
                    Me.Invalidate(r)
                Else
                    Me.Invalidate()
                End If
            Else
                Me.Invalidate()
            End If
            pt = Me.CurrentCellAddress
        End Sub

        Private Sub MultiHeaderDataGridView_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SizeChanged
            Me.Invalidate()
        End Sub

        Public Sub New()
            With Me
                .MultiSelect = False
                .SelectionMode = DataGridViewSelectionMode.CellSelect
                .DefaultCellStyle.SelectionBackColor = .DefaultCellStyle.BackColor
                .DefaultCellStyle.SelectionForeColor = .DefaultCellStyle.ForeColor
                .AllowUserToAddRows = False
            End With
        End Sub
    End Class
End Class
nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback