Laden...

Formatierung und Prüfung des Text während der Eingabe (Textbox)

Erstellt von Theo vor 10 Jahren Letzter Beitrag vor 10 Jahren 2.651 Views
T
Theo Themenstarter:in
40 Beiträge seit 2011
vor 10 Jahren
Formatierung und Prüfung des Text während der Eingabe (Textbox)

Hallo zusammen,

ich habe zwei Textboxen. Man kann es am besten damit erklären, wenn man sich vorstellt, die eine Textbox zeigt den aktuellen Kontostand an und bei der anderen kann ich eingeben, wieviel ich abheben will. Dem UserControl wird zu beginn ein Initialwert übergeben, der den Istwert darstellt. Nehmen wir mal an der Initialwert ist 3000

Beide Textboxen sind via Databinding an jeweils ein Property gebunden des UserControls gebunden.


this.tbActual.DataBindings.Add("Text", this, "ActualValue", true, DataSourceUpdateMode.OnPropertyChanged, 0, "###,###,###,###,##0");
this.tbTarget.DataBindings.Add("Text", this, "TargetValue", true, DataSourceUpdateMode.OnPropertyChanged, 0, "###,###,###,###,##0");

tbActual ist nicht aktiv, also der Nutzer kann nur bei tbTarget etwas eintragen. Damit der Nutzer keine negativen Werte öder höhere Werte als den Initialwert eingeben kann, hab sieht der set Aufruf des Properties wie folgt aus.


public Int64 TargetValue
{
    get { return targetValue; }
    set
    {
        targetValue = value;
                
        if (targetValue < 0)
            targetValue = 0;
        else if (targetValue > initialValue)
            targetValue = initialValue;

        ActualValue = initialValue - targetValue;
        NotifyPropertyChanged();
    }
}

Jetzt meine zwei Fragen dazu.

  1. Kann man irgendwo einstellen, dass die Formatierung der Textbox während des Tippens geupdatet wird. Jetzt kann ich Beispielsweise 1234 eingeben, aber das Tausendertrennzeichen wird erst gesetzt, wenn ich die Textbox verlasse. Ich hätte dies aber gern bei schon bei der Eingabe.

  2. Ich kann jetzt in der Textbox auch 123456 eingeben, also ein höherer Wert als der Initialwert (3000). Im set Aufruf des Properties passt auch alles, also die variable targetValue hat den Wert 3000 nur die Textbox zeigt was falsches an. Was kann man da am besten machen?

  3. Wenn ich nur Zahlen + Pfeiltasten (zum Navigieren in der Textbox) + Entf + Backspace zulassen will, kann ich dies nur mit dem Keydown-Event lösen, oder gibt es eine Eigenschaft der Textbox, wo man dies setzen kann?

Ich hatte ein ähnliches Problem schonmal ohne Databinding gelöst, da habe ich mich an das TextChanged-Event dran gehagen und habe die Formatierung da selbst übernommen. Dann musste ich aber auch den Cursor an die richtige Stelle setzen usw. Geht das eventuell eleganter?

Danke,
Theo

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo Theo,

zu 1: Du könntest eine Masked-TextBox verwenden.

zu 2. Beschränkungen auf Werte bringen Nachteile bei der Benutzung. Wenn bei einem Höchstwert von 3000 jemand gerade 900 ins Feld eingetippt hat und ihm just dann einfällt, dass er doch lieber 1000 möchte, dann kann er nicht einfach noch eine 0 hinten dran tippen, nach vorne springen, eine 1 tippen und dann die 9 löschen, weil schon nach der ersten 0 unerlaubte 9000 und nach der 1 unerlaubte 19000 im Feld stehen würden, bevor durch das Löschen der 9 mit 1000 wieder ein gültiger Wert erreicht ist. Deshalb finde ich es besser, Bereiche erst nach der Eingabe zu prüfen und während des Editierens (temporär) Bereichsüberschreitungen zuzulassen.

zu 3. Nein, Key-Down nützt dir nichts. Damit bekommst du die TextBox nicht dicht. Du musst TextChanged verwenden. Näheres in [FAQ] In einer TextBox nur bestimmte Zeichen/Eingaben zulassen.

herbivore

A
764 Beiträge seit 2007
vor 10 Jahren

Hallo Theo,

zu 2. noch ein kleine Idee, du könntest bei Bereichsüberschreitung den Text rot anzeigen, dann weiss der User bescheid, dass etwas nicht stimmt, kann aber trotzdem ungehemmt schreiben.

Gruß, Alf

T
Theo Themenstarter:in
40 Beiträge seit 2011
vor 10 Jahren

Danke für die Antworten,

Zu Punkt 1 und 2: Ich habe den Setter von TargetValue noch um die zwei Zeilen erweitert, damit hab ich beide Probleme erschlagen.


tbTarget.Text = targetValue.ToString("###,###,###,###,##0");
tbTarget.SelectionStart = tbTarget.TextLength;

@herbivore
Ich will in dem Fall genau nicht, dass der Nutzer frei größere Zahlen eintragen kann, sondern er soll direkt beim Eintippen limitiert werden, da sich der actualValue aus initialValue - targetValue berechnet und dies soll in dem Fall auch immer aktuell sein.

Zu 3)
Deine Textbox hab ich mir vorher schon angeschaut, aber hab ich da nicht das Problem mit der Formatierung? Ich müsste da ja auch als erlaubten char den Punkt (.) mit erlauben, aber um den soll sich der Nutzer ja nicht kümmern, oder sehe ich das falsch.

Theo

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo Theo,

Ich müsste da ja auch als erlaubten char den Punkt (.) mit erlauben

nein, Punkt brauchst du nicht zu erlauben. Du musst nur als ersten Schritt der Verarbeitung alle Punkte rauswerfen und als allerletzten Schritt wieder an den passenden Stellen einfügen.

Ich will in dem Fall genau nicht, dass der Nutzer frei größere Zahlen eintragen kann, sondern er soll direkt beim Eintippen limitiert werden, da sich der actualValue aus initialValue - targetValue berechnet und dies soll in dem Fall auch immer aktuell sein.

Also insbesondere in Kombination mit dem rot Einfärben von Werten außerhalb des Wertebereichs, finde meinen Vorschlag immer noch besser und für den Benutzer angenehmer. Das abhängige Feld kann bei Bereichsüberschreitungen des Ausgangsfeldes einfach auf dem letzten bekannten gültigen Wert stehen bleiben oder auch rot eingefärbt werden. Also alles lösbar.

herbivore

S
145 Beiträge seit 2013
vor 10 Jahren
tbTarget.SelectionStart = tbTarget.TextLength;

Würde ich nicht so machen, der Cursor sollte schon dastehen wo er zuletzt war, in anbetracht das plötzlich Punkte reinkommen an der "Zahlenstelle" wo er zuletzt war.

Ansonsten gerade bei Zahlen oder Datumsangaben empfiehlt es sich eher DataSourceUpdateMode.OnValidation zu verwenden, damit nicht gerade bei jedem eingegebenem Zeichen weitere prüfungsroutinen gestartet werden und/oder sofort der setter aufgerufen wird.