Für eine einfache Auflistung von Einträgen nimmt man für gewöhnlich die Standard-ListBox von VB. Möchte man dem Anwender jedoch das direkte Ändern von Einträgen innerhalb der ListBox gestatten, musste man bisher das ListView-Control verwenden, da man hier die erste Spalte editieren konnte. Ab sofort ist das aber auch für die Standard-ListBox möglich Alles was wir benötigen ist eine zusätzliche, zunächst unsichtbare TextBox (txtListEdit) auf der Form. Im DblClick-Ereignis der ListBox ermitteln wir dann den Eintrag, sowie dessen exakte Position, auf den der Doppelklick erfolgte und blenden dann einfach unsere TextBox über die ListBox. Starten Sie ein neues Projekt und platzieren auf die Form eine ListBox (List1), sowie eine TextBox (txtListEdit). Option Explicit ' Maus-Position Dim xPos As Single Dim yPos As Single ' Benötigte API-Deklarationen Private Declare Function SendMessage Lib "user32" _ Alias "SendMessageA" ( _ ByVal hWnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long Private Const LB_GETTOPINDEX = &H18E Private Const LB_GETITEMHEIGHT = &H1A1 Private Sub Form_Load() ' Liste mit Einträgen füllen Dim i As Integer For i = 1 To 100 List1.AddItem "Eintrag " & CStr(i) Next i ' TextBox verstecken txtListEdit.Visible = False End Sub Private Sub List1_MouseDown(Button As Integer, _ Shift As Integer, x As Single, y As Single) ' Mausposition merken xPos = x: yPos = y End Sub ' Bei Doppelklick - Editmode starten Private Sub List1_DblClick() Dim nTopIndex As Long Dim nItemHeight As Long Dim i As Long Dim nTop As Single Dim nIndex As Long ' Ermitteln des ersten Index der Listbox nTopIndex = SendMessage(List1.hWnd, LB_GETTOPINDEX, 0, 0) ' Ermitteln der Item-Zeichenhöhe nItemHeight = SendMessage(List1.hWnd, _ LB_GETITEMHEIGHT, 0, 0) * Screen.TwipsPerPixelY ' Ermitteln des Index, über dem der Mauspfeil steht nIndex = nTopIndex - 1 For i = 0 To List1.Height Step nItemHeight If i > yPos Then Exit For nIndex = nIndex + 1 Next ' Gültiger Index? If nIndex < List1.ListCount Then ' Textfeld positionieren und EditMode starten With txtListEdit .Left = List1.Left + 30 .Top = List1.Top + (nIndex - nTopIndex) * nItemHeight .Width = List1.Width - 315 .Text = List1.List(nIndex) ' Markierung in der ListBox ausblenden List1.Selected(nIndex) = False .Tag = nIndex .Visible = True .SetFocus End With End If End Sub So, jetzt lässt sich der ListBox-Eintrag schon mal editieren. Was fehlt jetzt noch? Genau! Der geänderte Text muss wieder in die ListBox übertragen werden - und zwar dann, wenn der Anwender die Enter-Taste drückt. Und bei dieser Gelegenheit: Drückt der Anwender die ESC-Taste soll die TextBox wieder "verschwinden" - ohne Textübertragung. Private Sub txtListEdit_KeyPress(KeyAscii As Integer) ' ESC und ENTER abfangen With txtListEdit If KeyAscii = 13 Then ' BEEP unterdrücken KeyAscii = 0 ' Eingabe in ListBox übernehmen List1.List(Val(.Tag)) = .Text ' Textfeld ausblenden .Visible = False List1.ListIndex = Val(.Tag) List1.SetFocus ElseIf KeyAscii = 27 Then ' BEEP unterdrücken KeyAscii = 0 ' Textfeld ausblenden .Visible = False List1.ListIndex = Val(.Tag) List1.SetFocus End If End With End Sub Ach ja: Der Text in der TextBox soll beim Starten des Editier-Modus auch gleich selektiert werden: Private Sub txtListEdit_GotFocus() ' Inhalt der TextBox markieren With txtListEdit .SelStart = 0 .SelLength = Len(.Text) End With End Sub Das funktioniert jetzt schon recht gut. Aber etwas fehlt immer noch Und zwar sollte die TextBox auch dann wieder "verschwinden", wenn der Anwender im EditMode auf eine anderen Eintrag in der ListBox klickt: Private Sub List1_GotFocus() ' Textfeld wieder verstecken txtListEdit.Visible = False End Sub Private Sub List1_Scroll() ' Textfeld wieder verstecken txtListEdit.Visible = False End Sub So, das war jetzt erst einmal. Ab sofort verfügt Ihre ListBox über eine AutoEdit-Funktion Viel Spaß damit! |