AutoCompletion advanced

    • VB.NET
    • .NET (FX) 4.5–4.8

    Es gibt 1 Antwort in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

      AutoCompletion advanced

      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
      • 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.
      Beispiel-Anwendung ist ein Orte-Finder, mit dem man aus ca. 16000 Ortsnamen mit normalerweise 3 Tastendrücken seinen Ort gefunden hat :D
      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

      1. Imports TextboxCoerceTester.OrteDts, System.IO
      2. Public Class frmOrtFinder
      3. Private WithEvents _Coercer As AutoCompletionCoercer
      4. Public Sub New()
      5. InitializeComponent()
      6. LoadData(Path.GetFullPath("..\..\Data\GeoNamesDE.inf"))
      7. _Coercer = New AutoCompletionCoercer(TextBox1)
      8. Dim data = OrteDts.Ort.Select(Function(rw) ", ".Between(rw.Name, rw.Bundesland, rw.PLZ))
      9. _Coercer.ReadData(data)
      10. End Sub
      11. Private Sub _Coercer_Changed(sender As Object, e As EventArgs) Handles _Coercer.AvailableCharsChanged
      12. lbAvailable.Text = _Coercer.AvailableChars
      13. End Sub
      14. Private Sub _Coercer_InputDone(sender As Object, e As EventArgs) Handles _Coercer.InputDone
      15. Dim s = _Coercer.CurrentValidWord.Split(","c)(0)
      16. bsOrt.MoveTo("Name", s)
      17. grdOrt.FirstDisplayedScrollingRowIndex = bsOrt.Position
      18. End Sub
      19. '...
      Also man deklarierts 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.
      Dateien
      Update

      Hab inzwischen gefunden (boah, ey!), dass auch Combobox AutoCompletion unterstützt.
      Was natürlich viel günstiger ist, denn Combobox kann man dann databindingmäßig integrieren, und mit einer Combo kann man ja von vornherein keinen Unfug eingeben.

      Und dann hab ich ein Popup-Fenster für die Anzeige der ValidKeys gebastelt. Dadurch braucht man im Oberflächen-Design auf die erweiterte Funktionalität nun keine Rücksicht mehr zu nehmen, die verschwindet nun ja von selbst, wenn nicht mehr gebraucht :)

      Das kl. Popup zeigt an: aer sind die zulässigen Tasten, mit der die Eingabe b gültigerweise fortfahren kann.
      Und bischn Klassen-Brimborium, damit die Logik, die ja sowohl für Combo- als auch für Text-boxen gilt, nur einmal geschrieben sein muss.

      Also das mit der Combo ist ziemlich fein, weil da kann man gleich mehrere Combos angeben.
      Und man braucht nichtmal die Daten-Items bereitzustellen, das liest er selber aus, aus der an die Combo gebundenen DataSource nämlich.
      Für die Combo-Funktionalität sind nun nur noch zwei Zeilen erforderlich:

      VB.NET-Quellcode

      1. Public Class frmOrtFinder
      2. Private _ComboPreview As New ComboboxCompletionPreview ' <- diese
      3. Public Sub New()
      4. InitializeComponent()
      5. '...
      6. _ComboPreview.SetCombos(cmbLand, cmbOrt) ' <- und diese, welche gleich 2 Combos konfiguriert
      7. End Sub

      Dateien

      Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ErfinderDesRades“ ()