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



  • @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



  • pascal2009 schrieb:

    Wenn das unleserlich ist: ich bin es nicht schuld!

    Doch, bist Du schuld weil Du keine Code-Tags benutzt. Aber das ist advanced Bedienung, also keine Panik.



  • Quatsch! Hat gar nix mit "advanced" Bedienung zu tuen. @pascal2009 Wenn du ernsthaft willst, das dir einer auf deine Beiträge im folgenden Antwortet, bitte benutze die C#-Code-Tags, so schwer ist das doch nicht, besonders weil ich es noch erklärt habe.



  • ************************************************************************
    ************************************************************************
    ****** LUXUSROUTINE FLIESSKOMMAEINGABE *********************************
    ************************************************************************
    ************************************************************************
    Lauffähiger Code, getestet, reicht für die nächsten 10 Jahre! 😉

    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) // FORMAT MASKE VOM SYSTEM = NO, weil KEIN FLIESSKOMMA, SONDERN FESTKOMMA
            {
            }
    
            private void textBox1_KeyDown(object sender, KeyEventArgs e)  //FRAGT DIE TASTEN AB
            {
                if (e.KeyCode == Keys.Enter) // ENTER-TASTE ERST JETZT ÜBERPRÜFUNG, VORHER NICHT! 
                {
                    int error = 0;
                    int dot=0;
                    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))) // NICHT AN POS ERSTE ODER LETZTE
                           { 
                               dot++; if (dot>1) error++;  //NATÜRLICH NUR 1 ERLAUBT
                           }
                           else error++;
                       }
                       else 
                       {
                          if (pruef[i]=='-')  // VORZEICHEN MINUS
                          {
                              if (i != 0) error++;  // NATÜRLICH NUR VORN ERLAUBT
                              else vorzeichen++;
                                                   }
                          else
                          {
                           if ( (pruef[i]<'0')|(pruef[i]>'9')) error++;  // DIE ZIFFERN
                          }  
                       }
                    } // Zählschleife
    
                    if (error != 0)  // MESSAGE NUR, WENN WAS VERKEHRT WAR
                    MessageBox.Show("Falsches Zahlenformat!\n Zulässige Zeichen \n Ziffern 0 - 9 \n Minus-Vorzeichen\n Dezimal-Trennzeichen: \n =Punkt kein Komma!");
    
              } // if ENTER
            }
    
           private void Form1_Load(object sender, EventArgs e)
           {
    
            } 
        } // textbox
    } // namespace
    


  • Wenn man so "zu Fuß" programmiert, braucht man sich um den ganzen Kram mit den "Cultures" und sonstigen Switches von C# nicht zu kümmern. "Cultures" 😉 was für ein Wort!

    Und hat es selbst in der Hand, Punkt oder Komma oder beides erlauben, oder ob man Dezimalpunkt ohne führende oder nachfolgende Nullen erlauben will, oder das 1000er Trennzeichen, man hat es ohne diese ganze Entwickleroberfläche mit den 1000 Switches im CODE eindeutig festgelegt, und kann das mit 3 Handgriffen ändern, wenn man will.

    Man hat alles selbst im Griff, egal was sich die integrierte Entwicklungsumgebung in der Zwischenzeit wieder an neuen "Cultures" zusammengebastelt hat!

    Die Konsole ist eben noch nicht raus aus dem Kopf! 😉

    MfG Pascal2009



  • Was bitte sind "Cultures"?



  • Firefighter schrieb:

    Was bitte sind "Cultures"?

    Ja das frage ich mich auch. Frag die Entwickler von C# 😉

    Wir sollten noch eine Kleinigkeit hinzufügen.

    Für den Fall Vorzeichen!=0 wär der DOT auf Stringpos 2 nicht erlaubt, für den fall ohne Vorzeichen ja.

    Das überprüfen wir am Ende der Zählschleife und achten drauf, daß Pos 1 im String =string[0], Pos2 im String = string[1] ist (!!);

    Demnach:

    } // Ende Zählschleife

    if ((vorzeichen > 0) && (pruef[1] == '.')) error++; // könnten wir erlauben, wollen wir aber nicht erlauben



  • Also damit du nicht lange suchen mußt:

    <%@ Page Language="C#" Culture="auto:en-US" UICulture="auto:en-US"%>
    <script runat="server">

    Das wo das Auto fährt, da ist die Kultur (denken die Amis). 😉


Anmelden zum Antworten