Laden...

Wie kann ich bei einer TextBox Eingabe nur ein bestimmtes Format erlauben?

Erstellt von Davidnh vor 3 Jahren Letzter Beitrag vor 3 Jahren 2.033 Views
D
Davidnh Themenstarter:in
21 Beiträge seit 2020
vor 3 Jahren
Wie kann ich bei einer TextBox Eingabe nur ein bestimmtes Format erlauben?

Hallo,

ich möchte eine TextBox als Eingabefeld für Temperaturen nutzen.
Den String der Eingabe möchte ich in eine Funktion auf Gültigkeit prüfen.
Erlaubt sein sollen alle Eingaben von bis zu zweistelligen Ganzzahlen oder Dezimalzahlen mit maximal einer Nachkommastelle. Also zb. :

1
20
1.5
14.4
...

Wie könnte ich dies realisieren?
LG

5.657 Beiträge seit 2006
vor 3 Jahren

Dazu reicht es, eine Eigenschaft mit einem numerischen Datentyp an eine normale Textbox zu binden. Hier gibt es ein Beispiel: Wie kann ich Focus auf Textbox setzen?

Siehe dazu: [Artikel] MVVM und DataBinding

Weeks of programming can save you hours of planning

D
Davidnh Themenstarter:in
21 Beiträge seit 2020
vor 3 Jahren

Hallo,

danke zunächst für die Antwort.
Mit dem Thema "Binding" habe ich noch arge Probleme.

Angenommen ich würde das mit dem Binden des Datentypen hinbekommen (was leider trotz des Beispieles irgendwie noch nicht klappen möchte), dann wären aber doch immer noch Zahlen mit mehreren Nachkommastellen erlaubt, wenn ich den Datentyp decimal nutze. Müsste ich dann erst einen eigene Datentyp erstellen, der dem gewünschten Format entspricht?

5.657 Beiträge seit 2006
vor 3 Jahren

Bindings sind in dem verlinkten Artikel ausführlich beschrieben. Bevor du mit WPF loslegst, solltest du dir das mal angeschaut haben.

Um die Anzahl der Dezimalstellen zu begrenzen, kannst du den Wert im Setter der Eigenschaft entsprechend runden. Oder du verwendest eine fertige Lösung, wie DoubleUpDown aus dem WPF Toolkit, dort kannst du (fast) alles konfigurieren.

Weeks of programming can save you hours of planning

D
Davidnh Themenstarter:in
21 Beiträge seit 2020
vor 3 Jahren

Es will mir einfach nicht gelingen..
Hast Du noch weitere Beispiele, die mir eventuell weiterhelfen könnten? 😃

LG

5.657 Beiträge seit 2006
vor 3 Jahren

Du mußt schon mal erklären, was du bisher probiert hast, und was nicht funktioniert, sonst kann man dir kaum helfen.

Weeks of programming can save you hours of planning

D
Davidnh Themenstarter:in
21 Beiträge seit 2020
vor 3 Jahren

Bisher löse ich es über eine Funktion.
Diese sorgt aktuell dafür, dass maximal zweistellig eingegeben werden kann und ein bestimmter Wertebereich nicht überschritten wird. Außerdem sind nur Zahlen möglich.

Die Möglichkeit einer Nachkommastelle fehlt jetzt natürlich noch komplett.

// Eingabeprüfung Temperatur
        private void Temperatur_TextChanged(object sender, TextChangedEventArgs e)
        {
            Timer_Eingaben_Übernehmen.Stop();
            Timer_Eingaben_Übernehmen.Start();

            TextBox Aktuelles_Eingabefeld = sender as TextBox;
            String Eingabe = Aktuelles_Eingabefeld.Text;
            
            if (Eingabe.Length > 2)
            {
                Aktuelles_Eingabefeld.Text = "";          
            }
            try
            {
                var x = Convert.ToInt32(Aktuelles_Eingabefeld.Text);
                if (x > Maximale_Temperatur)
                {
                    Aktuelles_Eingabefeld.Text = Convert.ToString(Maximale_Temperatur);
                }
            }
            catch
            {
                Aktuelles_Eingabefeld.Text = "";
            }

        }

Insgesamt sind auf der page 8 TextBoxen die Temperatureingaben ermöglichen sollen.

<TextBox x:Name="Temperatur_1"  TextWrapping="Wrap" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Margin="0" BorderBrush="{x:Null}" TextChanged="Temperatur_TextChanged" LostFocus="Eingabe_Temperatur_LostFocus"/>

Ich habe eine string Variable angelegt, wollte diese dann an Text binden und ein Stringformat vorgeben
Text="{Binding Temperatur, StringFormat={}{##.#}°C}"
Dies scheint aber nicht der richtige Weg zu sein... 😕

EDIT:
Ich habe es jetzt mit Hilfe dieses Beispiels (https://www.tutorialspoint.com/wpf/wpf_data_binding.htm) immerhin hinbekommen, dass das binding funktioniert.
Jetzt bleibt jedoch die große Frage:
Wie erreiche ich, dass nur Eingaben in dem gewünschten Format möglich sind?
Bei einer falschen Eingabe, soll einfach nichts geschehen und der bisherige Wert stehen bleiben

D
Davidnh Themenstarter:in
21 Beiträge seit 2020
vor 3 Jahren

Ich habe es jetzt mit einer Funktion gelöst...
Das ganze ist unendlich lang geraten, deswegen würde ich mich über eine Alternativlösung immer noch freuen 😃

 private void Eingabe_Temperatur_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            Regex regex_0 = new Regex(@"[0-9.]");
            Regex regex_1 = new Regex(@"[0-9]");

            TextBox Aktuelle_Textbox = sender as TextBox;
            String Aktueller_Inhalt = Aktuelle_Textbox.Text;
            int Inhaltlänge = Aktueller_Inhalt.Length;
            int Curserposition = Aktuelle_Textbox.CaretIndex;
            char Eingabezeichen = Convert.ToChar(e.Text);
            int Auswahllänge = Aktuelle_Textbox.SelectedText.Length;
            // Einfügen von mehr als einem Zeichen verhindern
            //MessageBox.Show(e.Text);

            // Für Eingabe Nur Zahlen und Punkte erluabt
            e.Handled = !regex_0.IsMatch(e.Text);

            // Wenn schon ein Punkt enthalten
            if (Aktueller_Inhalt.Contains('.'))
            {
                // Erlaubt keinen weiteren Punkt
                e.Handled = !regex_1.IsMatch(e.Text);

                int Punktposition = Aktueller_Inhalt.IndexOf('.');

                // Curser vor Punkt und schon zwei Zahlen davor
                if (Curserposition <= Punktposition && Punktposition == 2 )
                {
                    if (Auswahllänge == 0)
                    {
                        // Hier Maximaltemperatur einfügen
                        e.Handled = true;
                    }                   
                }
                // Nur eine Nachkommastelle erlaubt
                if (Curserposition > Punktposition && !Aktueller_Inhalt.EndsWith(".")) // Aktueller_Inhalt.Last() != '.'
                {
                    e.Handled = true;                    
                }
            }
         
            // Wenn noch kein Punkt enthalten
            else
            {
                // Wenn Punkt eingegeben wird
                if (Eingabezeichen == '.')
                {
                    if (Curserposition < 1 || Curserposition > 2)
                    {
                        e.Handled = true;
                    }
                }
                else if (Inhaltlänge == 2 && Auswahllänge == 0)
                {
                    e.Handled = true;
                }
            }
        }

        // Copy Paste in Eingabefeld verhindern
        private void Eingabe_PreviewExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            if (e.Command == ApplicationCommands.Paste)
            {
                e.Handled = true;
            }
        }

        private void Eingabe_Temperatur_LostFocus(object sender, RoutedEventArgs e)
        {
            TextBox Aktuelle_Textbox = sender as TextBox;
            String Aktueller_Inhalt = Aktuelle_Textbox.Text;

            // Wenn am Ende ein Punkt steht
            if (Aktueller_Inhalt.EndsWith("."))
            {
                Aktuelle_Textbox.Text = Aktueller_Inhalt + "0";
            }

            if (!Aktueller_Inhalt.Contains('.'))
            {
                Aktuelle_Textbox.Text = Aktueller_Inhalt + ".0";
            }

        }
D
261 Beiträge seit 2015
vor 3 Jahren

Im Grunde reicht dir das folgende Muster für Regex:

^[0-9]{1,}(.[0-9]{1,2})?$

Hier die Erklärung auf Englisch und Beispiel Matches: https://regex101.com/r/L2Drsf/1/

49.485 Beiträge seit 2005
vor 3 Jahren

Hallo Davidnh,

bei der Beschränkung von TextBox-Eingaben, kann man wirklich viel falsch machen.

Aus meiner Sicht, hast du den falschen Ansatz gewählt, weil du versuchst, unerwünschte Eingaben (=Tastendrücke) ganz weit vorne abzufangen. Besser ist es, abzuwarten, was die Eingaben für eine Textänderung bewirken und diese (TextChanged) dann zuzulassen oder eben nicht. Dann musst du z.B. auch das Clipboad nicht abklemmen.

Alles was man dazu wissen muss (auch die ganzen anderen Fallen, in die man hier tappen kann), steht in der [FAQ] In einer TextBox nur bestimmte Zeichen/Eingaben zulassen. Inkl. Beispielcode für eine sinnvolle Lösung.

herbivore