c# Windows Form Einlesen von Fließkommazahlen/formatiertes Einlesen
-
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ählschleifeif (error == 0) MessageBox.Show("Wert ist o.k. "+pruef);
else MessageBox.Show("Ungültiges Zahlenformat");} // if ENTER
} // textbox
} // ppp form1
} // namespaceDabei 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ählschleifeif (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"?