Eine AutoComplete-Funktion in einer TextBox ist schon etwas feines Doch wie lässt sich eine solche Autovervollständigungs-Funktion realisieren? Am liebsten wäre es uns natürlich, man würde ein TextBox-Control auf die Form ziehen ohne für jede TextBox dann eine eigene AutoComplete-Funktion proggen zu müssen. Was liegt also näher, die Standard-TextBox in einer Klassenbibliothek als neues VB.NET Control zu kapseln und diese dann durch entsprechende Eigenschaften und Methoden zu einer AutoComplete-TextBox zu erweitern? Let's go... Starten Sie die VS.NET Entwicklungsumgebung und wählen neues "Projekt erstellen". Als Projekt-Typ wählen Sie den Eintrag "Klassenbibliothek" aus und geben als Namen AutoCompleteTextBox ein. Für unser Beispiel benötigen wir außerdem die Klassen aus dem "Windows.Forms" Namespace. Aus diesem Grund müssen wir ein Verweis auf die Dll setzen. Hierzu klicken Sie bitte mit der rechten Maustaste auf den Knoten "Verweise" in ihrer Projektmappe und wählen den Befehl "Verweis hinzufügen". In dem darauf erscheinenden Dialog doppelklicken Sie auf den Eintrag "System.Windows.Forms(.dll)" und klicken anschließend auf OK. Die vorhandene Datei "Class1.vb" benennen wir am besten um, und zwar in "AutoCompleteTextBox.vb". Öffnen Sie jetzt diese Datei, löschen den existierenden Code und fügen nachfolgenden neuen Code ein. Option Explicit On Option Strict On ' // Die benötigten Bibliotheken für unser AutoCompleteTextBox Assembly Imports System.Windows.Forms Imports System.Collections Imports System ' // Der Namespace für unser Assembly Namespace AutoComplete Public Class AutoCompleteTextBox Inherits TextBox ' // Private Variablen Private m_wordList As AutoCompleteWordList Private m_autoComplete As Boolean Private m_insertByEnter As Boolean ' // Standardkonstruktor Public Sub New() MyBase.New() Me.m_wordList = New AutoCompleteWordList ' // WordListArray Instanz erzeugen Me.m_autoComplete = True Me.m_insertByEnter = True End Sub ' // Autocomplete (on/off?) Public Property AutoComplete() As Boolean Get Return Me.m_autoComplete End Get Set(ByVal value As Boolean) Me.m_autoComplete = value End Set End Property ' // Die Wörter automatisch beim drücken der Taste Enter bzw. Return hinzufügen (on/off?) Public Property InsertWordByEnter() As Boolean Get Return Me.m_insertByEnter End Get Set(ByVal value As Boolean) Me.m_insertByEnter = value End Set End Property ' // Das WordListArray Public Property WordList() As AutoCompleteWordList Get Return Me.m_wordList End Get Set(ByVal value As AutoCompleteWordList) Me.m_wordList = value End Set End Property ' // Wort hinzufügen Private Sub InsertWord(ByVal Word As String) ' // Befindet sich das Wort schon in der Liste? If (Me.m_wordList.IndexOf(New AutoComplete.AutoCompleteWord(Word)) = -1) Then ' // Nein. Wort hinzufügen Me.WordList.Add(New AutoComplete.AutoCompleteWord(Me.Text)) End If End Sub ' // Tastatureingaben kontrollieren/checken Private Function CheckKeys(ByVal e As KeyEventArgs) As Boolean If (Not Me.m_autoComplete OrElse _ Me.Text.Length < 1 OrElse _ e.KeyCode = Keys.Back OrElse _ e.KeyCode = Keys.Tab OrElse _ e.KeyCode = Keys.Delete) Then Return False ' // Return. Keine Aktion mehr durchführen ElseIf (m_insertByEnter AndAlso _ (e.KeyCode = Keys.Enter OrElse e.KeyCode = Keys.Return)) Then ' // Wort hinzufügen, da Enter bzw. Return gedrückt wurde Me.InsertWord(Me.Text) End If Return True End Function ' // Das eingegebene Wort vervollständigen Private Sub DoAutoCompleteText(ByVal e As KeyEventArgs) Static TextOld As String Dim pos, idx As Integer With Me If (TextOld Is Nothing OrElse Not .Text.Equals(TextOld)) Then idx = Me.WordList.IndexOf(New AutoComplete.AutoCompleteWord(.Text)) ' // Befindet sich das eigegebene Wort in unserem Array? ' // Hierfür wird keine "einfache" Schleife verwendet, sondern es wurde ein ' // eigene Word Klasse angelegt, in welcher die Equals() Methode überschrieben wurde. ' // Auf diese Methode greift wiederrum die ArrayList.IndexOf() Funktion zu. ' // Wir können sozusagen die Suche (bzw. das Verhalten der IndexOf() Methode) von der ArrayListKlasse ändern/steuern. If (idx > -1) Then ' // Ja, das Wort befindet sich in unseren WordListArray TextOld = .Text pos = .SelectionStart .Text = .Text + Me.WordList(idx).Word.Substring(.Text.Length) .SelectionStart = pos .SelectionLength = .Text.Length - (.SelectionStart) ' // SelectionStart/End usw. setzen Return End If End If End With End Sub Private Sub TextBox_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) _ Handles MyBase.KeyUp ' // Es wurde eine Taste in der TextBox gedrückt If (Not Me.CheckKeys(e)) Then Return Me.DoAutoCompleteText(e) End Sub End Class ' // Unsere etwas modifizierte ArrayList-Klasse Public Class AutoCompleteWordList Inherits ArrayList ' // Wort hinzufügen #1 (Value = WordObjekt) Public Overloads Function Add(ByVal value As AutoCompleteWord) As Integer MyBase.Add(value) End Function ' // Wort hinzufügen #2 (Value = String) Public Overloads Function Add(ByVal value As String) As Integer MyBase.Add(New AutoComplete.AutoCompleteWord(value)) End Function ' // Auf die Items (Wörter) zugreifen Default Public Shadows Property Item(ByVal index As Integer) As AutoCompleteWord Get Return CType(MyBase.Item(index), AutoComplete.AutoCompleteWord) End Get Set(ByVal Value As AutoCompleteWord) MyBase.Item(index) = Value End Set End Property ' // Die überschriebene Methode IndexOf() Public Shadows Function IndexOf(ByVal value As Object) As Integer ' // Ist Value ein String, müssen wir daraus ein AutoCompleteWord-Objekt erzeugen If value.GetType() Is GetType(String) Then Return MyBase.IndexOf(New AutoComplete.AutoCompleteWord(value.ToString())) Else ' // Value ist in diesen Fall schon ein AutoCompleteWord-Objekt, ' // kann demnach direkt übergeben werden Return MyBase.IndexOf(value) End If End Function End Class ' // Klasse AutoCompleteWord Public Class AutoCompleteWord ' // Private Variable Private m_Word As String ' // Konstruktor, mit Übergabe eines Wortes Public Sub New(ByVal Word As String) Me.m_Word = Word End Sub ' // Die überschreibene Methode Equals, auf welche wiederrum die IndexOf() ' // Methode zurückgreift (wie oben beschrieben) Public Overloads Overrides Function Equals(ByVal word As Object) As Boolean Return (CType(word, AutoCompleteWord).Word.StartsWith(Me.Word)) End Function ' // Das Wort zurückgeben Public Property Word() As String Get Return Me.m_Word End Get Set(ByVal Value As String) Me.m_Word = Value End Set End Property End Class End Namespace Jetzt können Sie den Code/das Projekt kompilieren. Drücken Sie hierfür bitte die Taste F5. Normalerweise sollte alles klappen, und die IDE einen Hinweis darüber ausgeben, dass eine Klassenbibliothek nicht direkt gestartet werden kann. Das ist auch richtig. Nun wollen wir natürlich auch dieses Assembly/Control benutzen bzw. testen.
Public Class Form1 Inherits System.Windows.Forms.Form #Region " Vom Windows Form Designer generierter Code " #End Region Private Sub Button2_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button2.Click Me.AutoCompleteTextBox1.WordList.Clear() End Sub Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' // Test-Eintrag für die AutoComplete-Liste Me.AutoCompleteTextBox1.WordList.Add("vbarchiv ist spitze") Me.AutoCompleteTextBox1.Text = String.Empty Me.Button1.Text = "Wort hinzufügen" Me.Button2.Text = "Wortliste leeren" Me.Button3.Text = "Wortliste anzeigen" Me.CheckBox1.Text = "Autocomplete" Me.CheckBox2.Text = "Insert word by enter" Me.CheckBox1.Checked = True Me.CheckBox2.Checked = True End Sub Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged Me.AutoCompleteTextBox1.AutoComplete = Me.CheckBox1.Checked End Sub Private Sub CheckBox2_CheckedChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged Me.AutoCompleteTextBox1.InsertWordByEnter = Me.CheckBox2.Checked End Sub Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click If Me.AutoCompleteTextBox1.WordList.IndexOf(Me.AutoCompleteTextBox1.Text) = -1 Then Me.AutoCompleteTextBox1.WordList.Add(Me.AutoCompleteTextBox1.Text) End If End Sub Private Sub Button3_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button3.Click Dim f As New Form Dim l As New ListBox l.DataSource = Me.AutoCompleteTextBox1.WordList l.DisplayMember = "Word" l.Dock = DockStyle.Fill f.Controls.Add(l) f.ShowDialog() End Sub End Class Ist dies getan, wollen wir das Control natürlich ausprobieren. Klicken Sie hierzu bitte mit der rechten Maustaste auf das "AutoCompleteTextBoxTestApp Projekt" und danach auf den Eintrag "Als Startobjekt festlegen". Jetzt kann das Programm mit F5 kompiliert und gestartet werden. Nach dem Start einfach einmal "vb" in der TextBox eingeben und siehe da, der Satz wurde vervollständig ) Dieser Tipp wurde bereits 17.931 mal aufgerufen. Voriger Tipp | Zufälliger Tipp | Nächster Tipp
Anzeige
Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv Vol.6 (einschl. Beispielprojekt!) Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! - nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten - Symbol-Galerie mit mehr als 3.200 Icons im modernen Look Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m. |
sevWizard für VB5/6 Professionelle Assistenten im Handumdrehen Erstellen Sie eigene Assistenten (Wizards) im Look & Feel von Windows 2000/XP - mit allem Komfort und zwar in Windeseile :-) Tipp des Monats Januar 2025 Dieter Otter Zeilen einer MultiLine-TextBox ermitteln (VB.NET) Dieser Zipp zeigt, wie man die Zeilen einer MultiLine-TextBox exakt so ermitteln kann, wie diese auch in der TextBox dargestellt werden. TOP Entwickler-Paket TOP-Preis!! Mit der Developer CD erhalten Sie insgesamt 24 Entwickler- komponenten und Windows-DLLs. Die Einzelkomponenten haben einen Gesamtwert von 1605.50 EUR... |
||||||||||||||||
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein. |