vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
SEPA-Dateien erstellen inkl. IBAN-, BLZ-/Kontonummernprüfung  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück
Rubrik:    |   VB-Versionen: VB2005, VB200802.01.10
Editierbare ListBox

Mit diesem Code erweitern Sie die Standard ListBox um die Möglichkeit, Einträge interaktiv per Doppelklick zu ändern.

Autor:  Dieter OtterBewertung:     [ Jetzt bewerten ]Views:  2.117 
http://www.tools4vb.de/System:  Win2k, WinXP, Win7, Win8, Win10, Win11 Beispielprojekt 

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, haben die meisten wohl das ListView-Control verwendet, 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 DoubleClick-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 (ListBox1), sowie eine TextBox (txtListEdit).

Public Class Form1
  ' wird benötigt, um auf das Scollen innerhalb 
  ' der ListBox reagieren zu können
  Private WithEvents oTimer As Timer
  Private Sub Form1_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load
 
    ' Listbox füllen
    For i As Integer = 1 To 100
      ListBox1.Items.Add("Eintrag " & CStr(i))
    Next
  End Sub
  Private Sub ListBox1_DoubleClick(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles ListBox1.DoubleClick
 
    With ListBox1
      ' Position des Eintrags ermitteln
      Dim p As Point = .PointToClient(Control.MousePosition)
 
      Dim index As Integer = .TopIndex - 1
 
      For i As Integer = 0 To .Height Step .ItemHeight
        If i > p.Y Then Exit For
        index += 1
      Next
 
      If index < .Items.Count Then
        ' TextBox einblenden
        txtListEdit.Location = New Point(.Left + 2, .Top + (index - .TopIndex) * .ItemHeight)
        txtListEdit.Width = .ClientRectangle.Width
        txtListEdit.Text = .Items(index).ToString
        txtListEdit.Tag = .TopIndex
        txtListEdit.Visible = True
        txtListEdit.Focus()
 
        ' Timer starten, damit wir mitbekommen, falls der User 
        ' über die Scrollbar die ListBox nach oben bzw. unten scrollt
        If IsNothing(oTimer) Then oTimer = New Timer
        oTimer.Interval = 50
        oTimer.Start()
      End If
    End With
  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(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtListEdit.KeyPress
 
    ' Tasten abfragen
    If Asc(e.KeyChar) = 13 Then
      ' ENTER
      e.Handled = True
 
      ' Eingabe in die ListBox übernehmen
      ListBox1.Items(ListBox1.SelectedIndex) = txtListEdit.Text
      ListBox1.Focus()
 
    ElseIf Asc(e.KeyChar) = 27 Then
      ' ESC - Textfeld ausblenden
      e.Handled = True
      ListBox1.Focus()
    End If
  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 ListBox1_GotFocus(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles ListBox1.GotFocus
 
    ' Textfeld ausblenden
    txtListEdit.Visible = False
  End Sub
  Private Sub oTimer_Tick(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles oTimer.Tick
 
    ' TopIndex der ListBox prüfen
    If ListBox1.TopIndex <> txtListEdit.Tag Then
      ' es wurde gescrollt ...
      ListBox1.Focus()
    End If
  End Sub

Sobald die TextBox ausgbelendet wurde, deaktiviern wir den Timer wieder:

  Private Sub txtListEdit_VisibleChanged(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles txtListEdit.VisibleChanged
 
    If txtListEdit.Visible = False Then
      ' Timer deaktivieren
      If Not IsNothing(oTimer) Then oTimer.Stop()
    End If
  End Sub
End Class

So, das war jetzt erst einmal. Ab sofort verfügt Ihre ListBox über eine AutoEdit-Funktion

Viel Spaß damit!