c# Windows Form Einlesen von Fließkommazahlen/formatiertes Einlesen



  • Ich habe mir für die Validierung im Internet mal Schnipsel angesehen, das ist ja alles furchtbar aufwendig außerdem verstehe ich den Code nicht und weiß nicht, wo ich den einbinden soll.

    Viel lieber würde ich es innerhalb der Win-Applikation so machen:

    eigene Funktion

    int Valid_string(string)
    {
    Schleife auf
    string aus dem Eingabefeld übernehmen
    in der gesamten Stringlänge absuchen, ob falsche Zeichen drin sind
    danach error setzen 0 oder 1
    return(errorcode)
    Schleife zu
    }

    Das ganze als Funktion für den Aufruf von TextBox einbinden, die TextBox soll dann solange weiter machen bis Eingabe o.k..

    Geht das, oder geht das nicht? Kann man innerhalb der Windows Applikation überhaupt in C# programmieren oder darf man da nur Windows-Funktionen aufrufen?

    Irgendwie ist das gerade im Anfang, für einen alten Konsolenprogrammierer, furchtbar unübersichtlich.

    Das Problem mit den float-Eingaben ist ja, wenn eine Standard-Validate den Wert 0 ermittelt, kann das ja trotzdem korrekt sein 0.0 ist ja zulässig.

    Gruß Pascal2009



  • Du kannst da drin genauso programmieren wie überall auch. Nutze dafür einfach Regular Expression, dazu solltest du dich mal schlau machen.



  • quick'n'dirty:

    void textBox1_TextChanged(object sender, EventArgs e)
    {
      double result;
      if(!double.TryParse(textBox1.Text, out result))
        MessageBox.Show("Keine Fließkommazahl.");
    }
    

    Lässt sich natürlich auch in andere EventHandler einbauen ( Button.Click z.B.) oder andere Fehlermeldungen etc...
    Eventuell musst du noch die richtige CultureInfo angeben angeben:

    void textBox1_TextChanged(object sender, EventArgs e)
    {
      double result;
      if(!double.TryParse(textBox1.Text, NumberStyles.Number, CultureInfo.CurrentCulture, out result))
        MessageBox.Show("Keine Fließkommazahl.");
    }
    


  • O.o schrieb:

    quick'n'dirty:

    void textBox1_TextChanged(object sender, EventArgs e)
    {
      double result;
      if(!double.TryParse(textBox1.Text, out result))
        MessageBox.Show("Keine Fließkommazahl.");
    }
    

    Lässt sich natürlich auch in andere EventHandler einbauen ( Button.Click z.B.) oder andere Fehlermeldungen etc...
    Eventuell musst du noch die richtige CultureInfo angeben angeben:

    void textBox1_TextChanged(object sender, EventArgs e)
    {
      double result;
      if(!double.TryParse(textBox1.Text, NumberStyles.Number, CultureInfo.CurrentCulture, out result))
        MessageBox.Show("Keine Fließkommazahl.");
    }
    

    Kurz und knapp, das sieht sehrt gut aus! Verglichen mit den abschreckenden Beispielen im Internet fast schon genial!

    Nimmt der Compiler auch!

    Nur daß er leider zeichenweise prüft. Ich müßte ihm jetzt noch sagen, wart mal auf die Enter_taste und prüfe dann. Setze ich aber accept Enter in den Eigenschaften von Textbox auf true, kommt er mit Fehlermeldung:

    Fehler 1 Datei "obj\Release\WindowsFormsApplication1.exe" kann nicht in "bin\Release\WindowsFormsApplication1.exe" kopiert werden. Der Prozess kann nicht auf die Datei "bin\Release\WindowsFormsApplication1.exe" zugreifen, da sie von einem anderen Prozess verwendet wird. WindowsFormsApplication1

    Wir nähern uns der Sache zwar langsam aber sicher an, aber der Weg dahin scheint doch recht steinig zu sein!

    Moment es heißt nicht accepts Enter, sondern accepts Return. Scheint wohl nicht dasselbe zu sein.

    MfG Pascal



  • O.o schrieb:

    Lässt sich natürlich auch in andere EventHandler einbauen (Button.Click z.B.)

    void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
      if(e.KeyCode == Keys.Return || e.KeyCode == Keys.Enter)
      {
        double result;
        if(!double.TryParse(textBox1.Text, NumberStyles.Number, CultureInfo.CurrentCulture, out result))
          MessageBox.Show("Keine Fließkommazahl.");
      }
    }
    

    Deine Fehlermeldung hat nichts mit TextBox.AcceptsReturn zu tun. Sie soll einfach heißen, dass er nichts in die Exe schreiben kann weil sie noch benutzt wird (aka das Programm läuft noch). Schau einfach mal im Taskmanager nach und beende dort den Prozess.



  • Wenn du "Enter" abfangen willst, dann mach das mit einem KeyDown oder KeyUp Event, dort kannst du die KeyEventArgs auf die Enter Taste überprüfen.



  • Das sieht jetzt schon ganz hervorragend aus!

    Die Eingabe beginnt rechtsbündig, und schiebt sich beim Eintippen nach links raus, wie das bei Fließkomma ja genau richtig ist, und man kann den Punkt so setzen, wie man will.

    Also Text-Vorgabe steht 0.00 drin, die werden aber von rechts kommend überschrieben.

    Das ist eine sehr "händige" Eingabe, wie man sie sich besser nicht wünschen kann.

    Problem aber: er wartet nicht auf Enter, sondern prüft bei jedem neuen Zeichen die Eingabe, z. B. ein - MInus Zeichen führt zur Fehlermeldung.

    Es fehlt also, daß die gesamte Eingabe erst mit Enter gelten soll. Das fehlt jetzt noch.



  • @firefox

    KeyEvents finde ich weder in den Eigenschaften von TextBox noch als separates Tool in der Toolbox.

    Bitte berücksichtige, daß ich mir dieses Programm vorgesteren spätabends erstmal runtergeladen habe und da gerade mal einige Stunden mit herumwurstele!



  • Ich habe jetzt folgendes Schnippsel entdeckt:

    this.textBox1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(CheckKeys);

    Then check which key was entered in the handler function:

    CODE
    private void CheckKeys(object sender, System.Windows.Forms.KeyPressEventArgs e)
    {
    if (e.KeyChar == (char)13)
    {
    // Then Enter key was pressed
    }
    }

    Der wirklich kongeniale Code von O.o. könnte damit mit einer if-Bedingung abgefangen werden.

    Nur leider finde ich keine passende Stelle, um das einzubauen. der Compiler ist immer am meckern.

    Der komplette Code sieht bislang so aus, und so läuft er auch, bis auf o.g. Problematik mit dem Enter:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    namespace WindowsFormsApplication1
    {

    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }

    private void textBox1_TextChanged(object sender, EventArgs e)

    {
    double result;
    if(!double.TryParse(textBox1.Text, out result))
    MessageBox.Show("Keine Fließkommazahl.");
    }

    }
    }



  • Hehe Firefighter is mein Name 😛 Aber egal.Die Events für deine Textbox findest du im Eigenschaftsfenster, dort befindet sich oben ein "gelber Blitz" und wenn du da drinne bist, gibt es ein KeyDown Event, sieht ungefähr so aus:
    Schau dir das Bild an.



  • So, jetzt läuft es perfekt!

    Und der code ist so, wie ich das liebe: kurz und knapp.

    Der Trick ist, die Eingabe auf keydown umzustellen, und die wunderbare Routine von O.o. mit einer If-Schleife abzufangen. Dazu nehmen wir e.KeyChar dazu

    Das geht so:

    private void CheckKeys(object sender, System.Windows.Forms.KeyPressEventArgs e)
    {
    if (e.KeyChar == (char)13)
    {
    // Then Enter key was pressed
    }
    }

    Jetzt fügt man die Validate-Prüfung auf fließkommazahl ein, sieht dann so aus:

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
    }
    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
    if (e.KeyCode == Keys.Enter)
    {
    double result;
    if (!double.TryParse(textBox1.Text, out result))
    MessageBox.Show("Keine Fließkommazahl.");
    }
    }

    Man kann dann in dem Eingabefeld alles eingeben, löschen, überschreiben und so weiter, bis man ENTER drückt. Erst in dem Augenblick wird der AUsdruck überprüft. Also genauso, wie es sein sollte!

    Und das schöne ist, daß man das Fließkomma zu jeder Zeit an jeder Stelle setzen kann, ein echtes Fließkomma.

    Und das alles in nur einer Handvoll Zeilen!

    MfG Pascal



  • Die ganze Routine auf einen Blick:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    namespace WindowsFormsApplication1
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }
    /*
    private void textBox1_TextChanged(object sender, EventArgs e)
    {
    }
    */
    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
    if (e.KeyCode == Keys.Enter)
    {

    double result;
    if (!double.TryParse(textBox1.Text, out result))
    MessageBox.Show("Keine Fließkommazahl.");
    }
    }
    }
    }



  • Bitte benutze doch die C#-Tags wenn du uns Code zeigst.Die befinden sich unter der Textbox in welcher du hier schreibst, neben dem Button "Latex".Somit ist der code für alle lesbarer.



  • Jetzt habe ich das Ganze noch etwas verfeinert (OK, das ist Anfänger-Code im Net zusammengesucht, aber es funktioniert).

    Hier wird der Umwandlungswert abgefangen, in einen neuen String gepackt und im Messageboard ausgegeben.

    Und was sehen wir? Da gibt es durchaus noch Probleme mit der Umwandlung, aus

    33.11 macht er 3311

    Das wird mit den Länderspezifischen Einstellungen zu tun haben. Im Prinzip läuft es aber jetzt schon ganz gut.

    namespace WindowsFormsApplication1
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }
    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
    if (e.KeyCode == Keys.Enter)
    {
    double result;
    if (!double.TryParse(textBox1.Text, out result))
    MessageBox.Show("Keine Fließkommazahl.");
    else
    {
    object o = new object();
    string s = o.ToString();
    double wert;
    double.TryParse(textBox1.Text, out wert);
    s = wert.ToString();
    MessageBox.Show(s);

    } //else
    } // if
    }//textbox1
    } // form1
    } //namespace



  • Zum einen heißt es "MessageBox" und zum anderen, was ist daran so schwer meinen Post zu befolgen und deinen Code in C#-Tags einzupacken?
    Sieht ungefähr so aus:

    [ cs] deincode[ /cs] //natürlich ohne Leerzeichen, aber sonst würde es nciht funktionieren

    Ohne Codeummantelung würde daraus folgendes werden

    namespace WindowsFormsApplication1
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }
    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
    if (e.KeyCode == Keys.Enter)
    {
    double result;
    if (!double.TryParse(textBox1.Text, out result))
    MessageBox.Show("Keine Fließkommazahl.");
    else
    {
    object o = new object();
    string s = o.ToString();
    double wert;
    double.TryParse(textBox1.Text, out wert);
    s = wert.ToString();
    MessageBox.Show(s);
    
    } //else
    } // if
    }//textbox1
    } // form1
    } //namespace
    

    Warum fummelst du da mit Objects rum? Ich glaube dir fehlen ein wenig die Grundlagen der OOP und das Verständnis was da passiert.



  • namespace WindowsFormsApplication1 
    { 
        public partial class Form1 : Form 
        { 
            public Form1() 
            { 
                InitializeComponent(); 
            } 
            private void textBox1_KeyDown(object sender, KeyEventArgs e) 
            { 
                if (e.KeyCode == Keys.Enter) 
                { 
                    double result; 
                    if (!double.TryParse(textBox1.Text, out result)) 
                        MessageBox.Show("Keine Fließkommazahl."); 
                    else 
                    { 
                        object o = new object();
                        string s = o.ToString();
                        double wert; 
                        double.TryParse(textBox1.Text, out wert); 
                        s = wert.ToString(); 
                        MessageBox.Show(s); 
                    } //else 
                } // if 
            }//textbox1 
        } // form1 
    } //namespace
    

    Dein Code mal leserlich. Und jetzt frag dich mal selbst, wofür du den else-Block brauchst, der eine ganze Menge überlüssigen Kram ausführt.



  • Dein Code mal leserlich. Und jetzt frag dich mal selbst, wofür du den else-Block brauchst, der eine ganze Menge überlüssigen Kram ausführt.[/quote]

    Diese ganze Abfrage über Systemfunktionen taugt nichts.

    Die TryParse funktion läßt mit double z.B. folgende Fehleingaben passieren:

    '-' mitten im String

    ',' auch mehrere

    '.' auch mehrere, auch an Pos. 1 und n

    Daneben ergibt der geprüfte STring abenteuerliche Umwandlungen,

    1.2345 = 12345

    Das ist mir alles nichts genaues.

    Mich wundert, daß so wichtige Formatierungen (Banken und GEschäftsbereich) nicht vom System fix und fertig verfügbar sind.

    Ich schreib dafür heute abend mal eine selbstdefinierte Funktion, und dann wird das passen.

    Frage zu dieser Funktion:

    In C++ würde ich die als void dezimaleingabe(*Adresse) vorneweg erkären, damit ich sie an jeder Stelle des Programms einbinden kann. Hier muß sich sie innerhalb von NameSpace und Form1 und TextBox erklären. Ich befürchte, daß man die daher von anderen Programmteilen nicht aufrufen können wird.

    WElche Möglichkeiten gibt es, die PUBLIC zu machen? Damit man sie nur einmal formulieren muß?

    Wie schon zutreffend gesagt wurde, bei der OOP da fehlt mir noch der Plan, wie man das strukturiert.

    MfG Pascal2009



  • Hier ist die Funktion nun.

    Sie liefert genau das, was eigentlich gemeint war, Zahlen in dem eigentlich international üblichen Fließkommaformat mit DOT.

    Es wäre natürlich schön, wenn man diese Funktion GLOBAL in das Programm einbinden könnte, wie gesagt eine Windows Forms Application

    namespace WindowsFormsApplication1
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
    }

    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
    if (e.KeyCode == Keys.Enter)
    {
    int error = 0;
    int dot=0;
    int vorzeichen = 0;
    string pruef;
    double wert;

    pruef = textBox1.Text;
    int slang = pruef.Length;
    for (int i = 0; i < slang; i++)
    {
    if (pruef[i]=='.')
    {
    if ((i > 0) && (i < (slang-1)))
    {
    dot++; if (dot>1) error++;
    }
    else error++;
    }
    else
    {
    if (pruef[i]=='-')
    {
    if (i != 0) error++;
    else vorzeichen++;
    }
    else
    {
    if ( (pruef[i]<'0')|(pruef[i]>'9')) error++;
    }
    }
    } // Zählschleife

    if (error == 0) MessageBox.Show("Wert ist o.k. "+pruef);
    else MessageBox.Show("Ungültiges Zahlenformat");

    } // if ENTER
    } // textbox
    } // ppp form1
    } // namespace

    Dabei ist mir aufgefallen, daß die Prüfung auf string[Length] ein falsche Funktion ergibt, er erkennt nicht, daß das Komma an der letzten Stelle steht, daher:

    if ((i > 0) && (i < (slang-1)))

    Kann es sein, daß die Funktion string.Length einen Wert liefert, der einen größer ist als die Zeichenkette, weil er die Endemarkierung \n oder was immer da stehen mag noch mitzählt?



  • doppel



  • ******************************************************
    LUXUSROUTINE zur Eingabe von FLIESSKOMMAZAHLEN
    ******************************************************

    Mit Komplettüberprüfung aller Zeichen. Die Eingabe erfolgt rechtsbündig, durch Aktivierung der TextBox Eigenschaft RighttoLeft=YES, wie es richtig, bequem und übersichtlich ist.

    Der Anwender kann in dem Feld machen, was er will, Backspace, Leertaste, Pfeiltasten, DEL wie auch immer, und sein Dezimaltrennzeichen setzen, wo er will und wann er will. Bis er Enter drückt.

    Ist die Eingabe korrekt, geschieht nichts, wenn nicht, erklärt die Message-Box exakt, was hier verlangt wird.

    Das Programm ist von meinem Editor exakt strukturiert, wenn ich es reinkopiere, aber der fertige Beitrag hier im Forum erscheint immer platt vor die linke Wand gedrückt. Nicht meine Schuld!

    Code ist lauffähig, getestet, funktionert 1A. Kann man für alle Fließkommaeingaben der nächsten 10 Jahre verwenden. 😉

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    namespace WindowsFormsApplication1
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
    }

    private void textBox1_KeyDown(object sender, KeyEventArgs e) //KEy-Down Ereignis wird abgefragt
    {
    if (e.KeyCode == Keys.Enter) // Bevor Enter gedrückt wird, passiert nichts.
    {
    int error = 0;
    int dot=0; // Dezimaltrennzeichen
    int vorzeichen = 0;
    string pruef="";

    pruef = textBox1.Text;
    int slang = pruef.Length;
    for (int i = 0; i < slang; i++)
    {
    if (pruef[i]=='.') // Dezimaltrennzeichen
    {
    if ((i > 0) && (i < (slang-1))) // Trennzeichen nicht erste nicht letzte
    // hier gibt es noch ein Phänomen: wenn i<slang (wäre Theoretisch die VOR-letzte Stelle)
    // akzeptiert er ein DOT auf dem Stringende.
    // da muß irgendwas sein, was er bei der Funktion string.Length dazuzählt, wahrscheinlich die Stringende-Markierung
    // Als Praktiker hab ich das erstmal mit Length-1 gelöst

    {
    dot++; if (dot>1) error++; // nur 1 Trennzeichen zulässig
    }
    else error++;
    }
    else
    {
    if (pruef[i]=='-')
    {
    if (i != 0) error++; // Minuszeichen nur vornean
    else vorzeichen++;
    }
    else
    {
    if ( (pruef[i]<'0')|(pruef[i]>'9')) error++; // die Ziffern
    }
    }
    } // Zählschleife

    if (error != 0) // Messagebox nur aufrufen, wenn was falsch ist
    MessageBox.Show("Falsches Zahlenformat!\n Zulässige Zeichen \n Ziffern 0 - 9 \n Minus\n Dezimal-Trennzeichen = Punkt \n kein Komma!");

    } // if ENTER
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    } // textbox
    } // ppp form1
    } // namespace


Anmelden zum Antworten