myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » GUI: WPF und XAML » Wie kann ich bei einer TextBox Eingabe nur ein bestimmtes Format erlauben?
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

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

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Davidnh Davidnh ist männlich
myCSharp.de-Mitglied

Dabei seit: 30.07.2020
Beiträge: 21
Entwicklungsumgebung: Visual Studio


Davidnh ist offline

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

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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
30.07.2020 12:00 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MrSparkle MrSparkle ist männlich
myCSharp.de-Team

avatar-2159.gif


Dabei seit: 16.05.2006
Beiträge: 5.426
Herkunft: Leipzig


MrSparkle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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
30.07.2020 12:29 Beiträge des Benutzers | zu Buddylist hinzufügen
Davidnh Davidnh ist männlich
myCSharp.de-Mitglied

Dabei seit: 30.07.2020
Beiträge: 21
Entwicklungsumgebung: Visual Studio

Themenstarter Thema begonnen von Davidnh

Davidnh ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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?
30.07.2020 13:15 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MrSparkle MrSparkle ist männlich
myCSharp.de-Team

avatar-2159.gif


Dabei seit: 16.05.2006
Beiträge: 5.426
Herkunft: Leipzig


MrSparkle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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.
30.07.2020 13:25 Beiträge des Benutzers | zu Buddylist hinzufügen
Davidnh Davidnh ist männlich
myCSharp.de-Mitglied

Dabei seit: 30.07.2020
Beiträge: 21
Entwicklungsumgebung: Visual Studio

Themenstarter Thema begonnen von Davidnh

Davidnh ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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

LG
30.07.2020 14:30 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MrSparkle MrSparkle ist männlich
myCSharp.de-Team

avatar-2159.gif


Dabei seit: 16.05.2006
Beiträge: 5.426
Herkunft: Leipzig


MrSparkle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Du mußt schon mal erklären, was du bisher probiert hast, und was nicht funktioniert, sonst kann man dir kaum helfen.
30.07.2020 16:29 Beiträge des Benutzers | zu Buddylist hinzufügen
Davidnh Davidnh ist männlich
myCSharp.de-Mitglied

Dabei seit: 30.07.2020
Beiträge: 21
Entwicklungsumgebung: Visual Studio

Themenstarter Thema begonnen von Davidnh

Davidnh ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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.

C#-Code:
// 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.

XML-Code:
<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

Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von Davidnh am 31.07.2020 08:57.

31.07.2020 08:10 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Davidnh Davidnh ist männlich
myCSharp.de-Mitglied

Dabei seit: 30.07.2020
Beiträge: 21
Entwicklungsumgebung: Visual Studio

Themenstarter Thema begonnen von Davidnh

Davidnh ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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 :)

C#-Code:
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";
            }

        }
31.07.2020 12:57 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dannoe
myCSharp.de-Mitglied

Dabei seit: 24.11.2015
Beiträge: 95
Entwicklungsumgebung: VS2005-VS2017


dannoe ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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

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

Hier die Erklärung auf Englisch und Beispiel Matches:  https://regex101.com/r/L2Drsf/1/
31.07.2020 13:58 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Poweruser/ Experte

avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.478
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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
31.07.2020 14:18 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 15.08.2020 07:05