vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Brandneu! sevEingabe v3.0 - Das Eingabecontrol der Superlative!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück
Rubrik:    |   VB-Versionen: VB4, VB5, VB601.06.04
CellClick Ereignis für das ListView Control

Beim Einsatz des Microsoft ListView-Controls such man leider vergebens nach einem CellClick-Ereignis. Wie man dieses Ereignis "nachbaut", um bspw. Inhalte einzelner Zellen zu editieren, das zeigen wir Ihnen mit diesem Extra-Tipp.

Autor:  Roland WutzkeBewertung:     [ Jetzt bewerten ]Views:  1.566 
http://www.vb-power.netSystem:  Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 Beispielprojekt 

Das ListView-Controls aus den Microsoft Common Controls eignet sich hervorragend um ungebundene Listen darzustellen. Leider verfügt das Control nur bedingt über die Möglichkeit, den Text einer Zelle zu editieren. Es kann lediglich eine Zelle in der ersten Spalte editiert werden. Doch was ist mit den übrigen Zellen? Geht nicht! Falsch, es geht doch...

Dazu folgende Überlegung: Wir benötigen als erstes eine Möglichkeit festzustellen, in welche Zelle der Anwender mit der Mouse geklickt hat. Doch wie kommen wir an diese Information? Die durch das ListView zur Verfügung gestellten Eigenschaften und Ereignisse liefern uns das leider nicht. Also greifen wir wieder in die API Trickkiste.

Über die SendMessage API-Funktion rufen wir den "HitTest" des Controls ab. So erhalten wir nicht nur die Mousekoordinaten, sondern auch noch direkt die Indizes für das Item und SubItem - also die Zelle unter der Mouse und somit auch den Text in der Zelle. Jetzt ist es ein leichtes den Text zu editieren

Doch wie setzen wir das jetzt um? Wir benötigen dafür ein Ereignis und somit ein Klassenmodul. Das Klassenmodul kapselt das übergebene ListView, ermittelt die Zelle unter der Mouse und erzeugt das Ereignis.

Die Klasse "clsLvwCellClick"

Erstellen Sie ein neues Projekt und legen ein leeres Klassenmodul an. Benennen Sie die Klasse "clsLvwCellClick". Fügen Sie den folgenden Code in das Klassenmodul ein.

' ****************************************************************
' *
' *   clsLvwCellClick - VB6 Klassenmodul
' *
' *   Das Klassenmodul kapselt ein ListView und wertet über
' *   die SendMessage API den HitTest aus. Dabei wird die
' *   aktuelle Zelle unter der Mouse ermittelt.
' *
' *   Eigenschaft: oListView - übergeben wird das ListView
' *                aus der aufrufenden Form.
' *
' *   Ereignis: CellClick - zurückgegeben wird der ButtonStatus,
' *             die Zeile, die Spalte, der EditModus und
' *             der CellText an die Form.
' *
' *   Im Ereignis der Form kann der CellText editiert und wieder
' *   an die Klasse zurückgegeben werden. Der editierte Text
' *   wird dann in das ListView an die ursprüngliche Position
' *   eingetragen.
' *
' *   Mai 2004, www.vb-power.net und Roland Wutzke
' *
' ****************************************************************
 
Option Explicit
 
' benötigte API-Deklarationen
Private Declare Function SendMessage Lib "user32" _
  Alias "SendMessageA" ( _
  ByVal hwnd As Long, _
  ByVal wMsg As Long, _
  ByVal wParam As Long, _
  lParam As Any) As Long
 
' ListView Konstanten
Private Const LVM_FIRST As Long = &H1000
Private Const LVM_SUBITEMHITTEST As Long = (LVM_FIRST + 57)
Private Const LVHT_ONITEM As Long = &HE
 
' Type Info´s
Private Type POINTAPI
  x As Long
  y As Long
End Type
 
Private Type lvwInfo
  pApi As POINTAPI
  Flags As Long
  lItem As Long
  lSubItem  As Long
End Type
 
' KlassenVars
Private WithEvents cListView As ListView
 
' Ereignis
Public Event CellClick(ByVal ButtonState As Integer, _
  ByVal Row As Long, ByVal Col As Long, _
  EditMode As Boolean, CellText As String)
' Eigenschaften der Klasse
Public Property Set oListView(ByVal vData As ListView)
  Set cListView = vData
End Property
' --------------------------------------------------------------
' Hauptroutine - hier wird im MouseDown Ereignis des übergebenen
' ListView Controls der Klick mit der Mouse registriert und
' verarbeitet. Dabei wird über die SendMessage API der HitTest
' des Controls abgerufen und in pLVWInfo gespeichert. Der Vorteil
' dieser Methode ist, dass zusätzlich noch die Item- und SubItem
' Indizes zurückgegeben werden. Diese werden über das Ereignis
' CellClick Row und Col an die aufrufende Form übergeben. Hierbei
' ist zu beachten, dass für Row der Index+1 erhöht wurde, damit
' Row bei 1 zu zählen beginnt. Für Col ist zu beachten, dass
' Col(1) die Spalte mit dem Item und alle weiteren Spalten Col(2-n)
' die SubItems enthalten. Mit CellText wird der Text unter der
' Mouse übergeben. Dieser kann in der aufrufenden Form editiert
' und wieder an die Klasse zurückgegeben werden. Der String wird
' anschließend in der Klasse in das ListView eingetragen.
' Gesteuert wird das über die BooleanVar EditMode, die den
' Wert=True haben muss, um den Text einzutragen.
' --------------------------------------------------------------
 
Private Sub cListView_MouseDown(Button As Integer, _
  Shift As Integer, x As Single, y As Single)
 
  Dim pLVWInfo As lvwInfo
  Dim tmpX As Long
  Dim tmpY As Long
  Dim pEditMode As Boolean
  Dim tmpText As String
 
  ' LVWInfo vorbesetzen
  With pLVWInfo
    .pApi.x = x \ Screen.TwipsPerPixelX
    .pApi.y = y \ Screen.TwipsPerPixelY
    .Flags = LVHT_ONITEM
  End With
 
  ' LVWInfo über den HitTest des Listviews ermitteln
  Call SendMessage(cListView.hwnd, LVM_SUBITEMHITTEST, 0, pLVWInfo)
 
  ' LVWInfo auswerten
  With pLVWInfo
    ' wurde auf ein Item geklickt?
    If .lSubItem = 0 Then
      If .lItem > -1 Then
        ' Eigenschaften vorbesetzen
        tmpX = .lItem + 1
        tmpY = 1
        pEditMode = False
        tmpText = cListView.ListItems(tmpX).Text
        cListView.ListItems(tmpX).Selected = True
        ' Ereignis auslösen
        RaiseEvent CellClick(Button, tmpX, tmpY, pEditMode, tmpText)
        ' wurde ein neuer CellText zurückgegeben?
        If pEditMode Then
          cListView.ListItems(tmpX).Text = tmpText
          cListView.Refresh
          DoEvents
        End If
      End If
 
    ' wurde auf ein SubItem geklickt?
    ElseIf .lSubItem > 0 Then
      If .lItem > -1 Then
        ' Eigenschaften vorbesetzen
        tmpX = .lItem + 1
        tmpY = .lSubItem
        pEditMode = False
        tmpText = cListView.ListItems(tmpX).SubItems(tmpY)
        cListView.ListItems(tmpX).Selected = True
        ' Ereignis auslösen
        RaiseEvent CellClick(Button, tmpX, tmpY + 1, pEditMode, tmpText)
        ' wurde ein neuer CellText zurückgegeben?
        If pEditMode Then
          cListView.ListItems(tmpX).SubItems(tmpY) = tmpText
          cListView.Refresh
          DoEvents
        End If
      End If
    End If
  End With
End Sub
' Klasse terminieren
Private Sub Class_Terminate()
  If Not cListView Is Nothing Then
    Set cListView = Nothing
  End If
End Sub

Wie wird nun die Klasse genutzt und vor allen Dingen, wie wird der CellText editiert? Alles das demonstriert Ihnen eindrucksvoll unser Beispielprojekt, das es hier zum downloaden gibt.

Viel Spaß...