Rubrik: Controls · DataGrid & DataGridView | VB-Versionen: VB2010 | 07.02.11 |
Selektierte Zeile unterstreichen (DataGridView) Es wird eine Funktion vorgestellt, die es erlaubt, die selektierte Zeile mit einer Linie zu unterstreichen und damit zu kennzeichnen (entweder nur mit der Linie oder in Kombination mit der 'normalen' Selektion). | ||
Autor: Dietrich Herrmann | Bewertung: | Views: 10.239 |
ohne Homepage | System: Win2k, WinXP, Win7, Win8, Win10, Win11 | Beispielprojekt auf CD |
Die Vorgehensweise ist folgende:
In der Form mit dem DatagridView vereinbart man zunächst bspw. mit
Dim lineLabel As New Label
das zu verwendente Label für die Linie.
Im FormLoad-Ereignis verwendet man dann die unten gezeigte Prozedur im 'Startmodus' (erster Parameter = 1, bedeutet, dass zunächst nur das Label für die Verwendung 'konstruiert' wird):
Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load drawLabelOnDGV(1, Me.DataGridView1, lineLabel, Me, 2, Color.Red) End Sub
Damit wird angegeben, über welchem DGV gezeichnet werden soll; welcher Label genommen wird; zu welchem Parent-Control das DGV gehört (hier die Form selbst); die Dicke der Linie, hier 2; die Farbe der Linie, hier RED.
Im Ereignis DataBindingComplete des DGV wird die Funktion folgendermaßen ausgeführt im Modus 'Initialisieren der Labelbreite' (erster Parameter 2):
Private Sub DataGridView1_DataBindingComplete(ByVal sender As Object, _ ByVal e As System.Windows.Forms.DataGridViewBindingCompleteEventArgs) _ Handles DataGridView1.DataBindingComplete drawLabelOnDGV(2, DataGridView1, lineLabel, Me) End Sub
Im Ereignis RowPostPaint des DGV führt man dann die Funktion im 'Positioniermodus' (erster Parameter 3) aus:
Private Sub DataGridView1_RowPostPaint(ByVal sender As Object, _ ByVal e As System.Windows.Forms.DataGridViewRowPostPaintEventArgs) _ Handles DataGridView1.RowPostPaint drawLabelOnDGV(3, DataGridView1, lineLabel, Me) End Sub
Und hier der gesamte Code der Prozedur drawLabelOnDGV:
''' <summary> ''' zeichnen einer Linie (mittels Label) auf Datagridview unter die selektierte Zeile ''' </summary> ''' <param name="art">Verwendungsart der Funktion (1|2|3)</param> ''' <param name="theDGV">das DatagridView</param> ''' <param name="theLabel">das Label-Control</param> ''' <param name="parCtrl">das Parent-Control oder -Form des DGV</param> ''' <param name="labHeight">Label-Höhe</param> ''' <param name="labColor">Label-Backcolor</param> ''' <param name="clrSel">zusätzlich Selection im DGV zeigen(False) oder nicht(True)</param> Public Sub drawLabelOnDGV(ByVal art As Short, ByVal theDGV As DataGridView, _ ByVal theLabel As Label, _ ByVal parCtrl As Object, _ Optional ByVal labHeight As Short = 0, _ Optional ByVal labColor As Color = Nothing, _ Optional ByVal clrSel As Boolean = True) Dim rect As Rectangle Select Case art Case 1 ' bei Start der Form erfolgt Definition des Labels With theLabel .Parent = theDGV .BackColor = labColor .BorderStyle = BorderStyle.None .AutoSize = False .Text = "" .Height = labHeight .BringToFront() End With Case 2 ' wenn DataBindingCompleted des DGV, dann die Länge des Labels berechnen With theLabel .Visible = (theDGV.RowCount > 0) ' wenn keine Zeile im DGV, dann Label unsichtbar If theDGV.RowCount <= 0 Then Exit Sub rect = theDGV.GetRowDisplayRectangle(0, False) ' das Rechteck der ersten Zeile .Top = rect.Bottom ' der Label soll unter die Zeile gezeichnet werden .Left = theDGV.RowHeadersWidth .Width = calcDGVWidth(theDGV) ' berechnen der aktuellen DGV-Breite If theDGV.RowHeadersVisible Then .Width -= theDGV.RowHeadersWidth ' prüfen, ob Höhe des DGV größer als die Höhe des Parentcontrols ' wenn ja, dann wird vertikale Scrollleiste angezeigt If theDGV.PreferredSize.Height > parCtrl.ClientSize.Height Then .Width -= SystemInformation.VerticalScrollBarWidth End If .Invalidate() End With Case 3 ' berechnen der Position des Labels gemäß selektierter Zeile With theDGV If clrSel Then .ClearSelection() ' Selection anzeigen/nicht anzeigen ' die aktuelle Zeile gibt Positionsdaten vor rect = .GetRowDisplayRectangle(.CurrentRow.Index, False) ' das Rechteck der aktuellen Zeile theLabel.Top = rect.Bottom ' der Label soll unter die Zeile gezeichnet werden theLabel.Left = .RowHeadersWidth End With End Select End Sub
Man benötigt noch die Hilfsfunktion calcDGVWidth, die zur Berechnung der aktuellen Breite eines DGV verwendet wird.
''' <summary> ''' Berechnen der aktuellen Breite eines Datagridview ''' </summary> ''' <param name="theDGV">das DatagridView</param> ''' <returns>Breite des DatagridView</returns> Public Function calcDGVWidth(ByVal theDGV As DataGridView) As Integer Dim theWidth As Integer With theDGV For Each c As DataGridViewColumn In .Columns If c.Visible = True Then theWidth += c.Width ' nur sichtbare Spaltenbreiten addieren Next If .RowHeadersVisible Then theWidth += .RowHeadersWidth If .Controls(1).Visible Then ' ist die vertikale Scrollbar aktuell sichtbar? theWidth += SystemInformation.VerticalScrollBarWidth ' Breite der Scrollbar End If End With Return theWidth End Function
Wenn man bspw. zur SelectionBackcolor eine 'passende' Farbe der Linie nimmt und dann beides anzeigen lässt, eventuell mit SelectionMode = DataGridViewSelectionMode.FullRowSelect kann man einen 'etwas anderen' Effekt erzielen...