Für das Aussuchen eines bestimmten Strings aus einer großen Datenmenge gibts bislang keine wirklich überzeugenden Lösungen.
Eine Combobox mit 5000 Item kann einfach man niemandem anbieten, selbst wenn sie sortiert sind.
Dann schon eher eine Textbox mit AutoCompletion.
Die bietet aber keinen Schutz gegen Fehleingaben.
Zusätzliches Manko, dass bei großen Datenmengen noch immer zu viele Vorschläge präsentiert werden. Nämlich etwa in einer Namensliste bekommt der User-Input "M" alle Mayers vorgeschlagen, und das sind u.U. so viele, dass er denkt, nun müsse er mit "a" weiter schreiben, denn die Meiers und Müllers etc. sind ausserhalb des sichtbaren Bereichs der VorschlagListe.
Jedenfalls mein Lösungs-Ansatz:
Ein Textbox-Behavior mit AutoCompletion, das zusätzlich
Bildle:
-
Bild1 sind die Vorschläge zu "re" - man sieht, dass die AutoCompletion schon aus Platzgründen nur Fortsetzungen mit "c" vorschlagen kann. Deshalb werden über der Textbox die AvailableChars angezeigt, dass man sieht, es sind noch ca. 15 weitere Fortsetzungen valide.
Bild2 zeigt dann den nächsten Tastendruck "g", und damit ist die Suche bereits so stark eingegrenzt, dass man abschließen kann.
An Datenverarbeitung ist noch ein DGV dran-programmiert, was dann zum ausgewählten Datensatz navigiert
Die 16000 Ortsnamen sind übrigens von GeoNames bezogen, unter "Creative Commons Attribution 3.0 License", die besagt freie Verfügbarkeit, solange man den Autor in den Credits erwähnt.
Dem ich hiermit gerne nachkomme .
Jo, der Code ist sehr trickreich, und weil ich zu faul bin, das Helpers-Projekt rückzubauen, scheints ziemlich umfangreich.
Wogegen die eigentliche Benutzung sehr einfach ist:
Also man deklarierts
Auch die eigentlichen Klassen sind mit je 100 Zeilen eiglich sehr schlank - fett ist nur die Helpers-Lib, von der ich aber auch nur glaub 5 Methoden verwende.
Ja, also wer Lust hat, mags ein bischen testen - das Teil ist halt neu, daher erwarte ich fast, dass noch der eine oder andere Bug drin rumkrabbelt.
Eine Combobox mit 5000 Item kann einfach man niemandem anbieten, selbst wenn sie sortiert sind.
Dann schon eher eine Textbox mit AutoCompletion.
Die bietet aber keinen Schutz gegen Fehleingaben.
Zusätzliches Manko, dass bei großen Datenmengen noch immer zu viele Vorschläge präsentiert werden. Nämlich etwa in einer Namensliste bekommt der User-Input "M" alle Mayers vorgeschlagen, und das sind u.U. so viele, dass er denkt, nun müsse er mit "a" weiter schreiben, denn die Meiers und Müllers etc. sind ausserhalb des sichtbaren Bereichs der VorschlagListe.
Jedenfalls mein Lösungs-Ansatz:
Ein Textbox-Behavior mit AutoCompletion, das zusätzlich
- anzeigt, welche Buchstaben als nächstes drückbar sind
- unzulässige Tastendrücke unterdrückt
- die Eingabe "vorspult", wenn eh nur eine einzige Eingabe-Option valide ist
- beim Verlassen der Textbox auf jeden Fall einen gültigen Eintrag einträgt.
Bildle:
-
Bild1 sind die Vorschläge zu "re" - man sieht, dass die AutoCompletion schon aus Platzgründen nur Fortsetzungen mit "c" vorschlagen kann. Deshalb werden über der Textbox die AvailableChars angezeigt, dass man sieht, es sind noch ca. 15 weitere Fortsetzungen valide.
Bild2 zeigt dann den nächsten Tastendruck "g", und damit ist die Suche bereits so stark eingegrenzt, dass man abschließen kann.
An Datenverarbeitung ist noch ein DGV dran-programmiert, was dann zum ausgewählten Datensatz navigiert
Die 16000 Ortsnamen sind übrigens von GeoNames bezogen, unter "Creative Commons Attribution 3.0 License", die besagt freie Verfügbarkeit, solange man den Autor in den Credits erwähnt.
Dem ich hiermit gerne nachkomme .
Jo, der Code ist sehr trickreich, und weil ich zu faul bin, das Helpers-Projekt rückzubauen, scheints ziemlich umfangreich.
Wogegen die eigentliche Benutzung sehr einfach ist:
VB.NET-Quellcode
- Imports TextboxCoerceTester.OrteDts, System.IO
- Public Class frmOrtFinder
- Private WithEvents _Coercer As AutoCompletionCoercer
- Public Sub New()
- InitializeComponent()
- LoadData(Path.GetFullPath("..\..\Data\GeoNamesDE.inf"))
- _Coercer = New AutoCompletionCoercer(TextBox1)
- Dim data = OrteDts.Ort.Select(Function(rw) ", ".Between(rw.Name, rw.Bundesland, rw.PLZ))
- _Coercer.ReadData(data)
- End Sub
- Private Sub _Coercer_Changed(sender As Object, e As EventArgs) Handles _Coercer.AvailableCharsChanged
- lbAvailable.Text = _Coercer.AvailableChars
- End Sub
- Private Sub _Coercer_InputDone(sender As Object, e As EventArgs) Handles _Coercer.InputDone
- Dim s = _Coercer.CurrentValidWord.Split(","c)(0)
- bsOrt.MoveTo("Name", s)
- grdOrt.FirstDisplayedScrollingRowIndex = bsOrt.Position
- End Sub
- '...
Withevents
(zeile #5), instanzierts mit der gewünschten Textbox (#10), füllt die Daten ein (#12) und kann die Events AvailableCharsChanged
und InputDone
verarbeiten (#15, #19).Auch die eigentlichen Klassen sind mit je 100 Zeilen eiglich sehr schlank - fett ist nur die Helpers-Lib, von der ich aber auch nur glaub 5 Methoden verwende.
Ja, also wer Lust hat, mags ein bischen testen - das Teil ist halt neu, daher erwarte ich fast, dass noch der eine oder andere Bug drin rumkrabbelt.