Dont make me think. Textbox Eingaben Filtern

Üblicherweise kennt man seine Pappenheimer. Im Falle von Windows 8 Store APPs, kennt man sie aber nicht. Nicht mal den Tester kennt man, geschweige denn könnte man nachfragen oder ihn gar anrufen.

Die Aufgabe die ein Benutzer bekommt. Schreibe hier deinen Server Namen hin. Ergebnis bisher:

  • http://Server.de
  • //server.de
  • https://server.de
  • //server

Natürlich könnte man episch den Windows Dialog füllen mit umfangreichen beschreibenden Hinweisen. Ich bin allerdings der Meinung das “Server Name” reichen muss. Kürzere Texte lassen sich schneller lesen. Darüber hinaus liest doch ohnehin keiner mehr was. Oder man baut umfangreiche Logik, die die Daten sozusagen normalisiert.

Besser wäre es, wenn der Benutzer genau weis, was da rein gehört, bzw. einen eindeutigen Hinweis erhält wenn es nicht stimmt. Ich habe schon beschrieben, das eine Fehlermeldung direkt über der Textbox das beste Feedback an den User gibt.

Jetzt stellt sich die Frage, wie filtert man die Tastatureingaben in der Textbox?

Es gibt jedenfalls keine Möglichkeit, direkt z.B. mit regular Expressions Tastaturcodes zu filtern. Es gibt auch kein FilteredTextbox Steuerelement direkt von Microsoft.

Der nächste Ansatz lässt einen das Keydown Event der Textbox vermuten, wie folgender einfacher VB.NET Code zeigt.

Private Sub text1_KeyDown_1(sender As Object, e As KeyRoutedEventArgs)
        output1.Text = e.Key.ToString + "-" + e.KeyStatus.ScanCode.ToString
 End Sub

Allerdings sind das wirklich die Keys. Also sowohl Doppelpunkt : als auch Punkt . liefern auf einer deutschen (und nur dort) den gleichen Code, nämlich 190. Manche Szenarien, wie die Beschränkung auf numerische Eingaben lassen sich in der Tat so lösen. Einfach nur im Filterfall e.handled=true und schon verschwindet das Zeichen. (Scancode ist 52 und ebenfalls ident).

Man kann allerdings die Zeichen auslesen mit dem CharacterReceived Event. Das ist einigermaßen kompliziert über Umwege in .NET WinRT zu erreichen. Im folgenden VB Beispiel ergibt sich so für den : 58 und für den . 46.

Private Sub MainPage_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Dim c As CoreWindow = CoreWindow.GetForCurrentThread
        AddHandler c.CharacterReceived, AddressOf somenewkeyarrived
End Sub

Private Sub somenewkeyarrived(sender As CoreWindow, args As CharacterReceivedEventArgs)
        output1.Text = args.KeyCode
        args.Handled = True
End Sub

Leider hilft uns das kaum weiter. Wir wissen zwar das böse / oder : gekommen sind, aber was tun?

Kommen wir zum Dritten Ansatz, das Event TextChanged. Hier wird einfach der gesuchte Character per Replace wieder ersetzt. Allerdings steht dann der Cursor in der Textbox am Anfang und muss mit zwei Zeilen wieder in die vorige Position gesetzt werden.

Private Sub text1_TextChanged_1(sender As Object, e As TextChangedEventArgs)
        If sender.text.contains(":") Then
            output1.Text = sender.text
            Dim i = sender.selectionstart
            sender.text = sender.text.replace(":", "")
            sender.selectionstart = i - 1
        End If
End Sub

Das funktioniert zwar, benötigt aber eine Menge Code im User Interface. Wünschenswert wäre ein XAML Attribut ala FilterCharacters.

Wenn man sich mit MVVM beschäftigt, bleibt ohnehin nur das Event Lostfocus. Erst danach wird ein gebundenes Datenobjekt aktualisiert und kann auf Gültigkeit überprüft werden. Einen UpdateSourceTrigger wie in WPF gibt es jedenfalls auch nicht in WinRT XAML.

Kommentare sind geschlossen