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 |