[Windows Forms] Länge der Nachkommastellen von Textboxen einstellen?
-
Hi, wer weiss wie man einstellen kann wie viele Nachkommastellen in einer Textbox angezeigt werden sollen? Bei den Properties hab ich es nicht gefunden.
Toll wäre auch wenn man gar keine Buchstaben und Sonderzeichen mehr reinschreiben könnte, es sollen in den Felder ausschliesslich Zahlen mit maximal 2 Nachkommastellen eingetragen werden können.
-
Hi!
Schon mal überlegt ein OnTextChange-event zu nutzen?
Damit kannst du den String in ein char-array umwandeln.
Rückgabewert ist die Länge des Strings.
Von da an müsstest du mit Schleifen und Ascii weiterkommen.int Misc::StrToCharArray(System::String * tempStr,char* CharArray) { if (tempStr == NULL) return -102001901; // ERROR: instance is missing int charsOfStr=tempStr->get_Length(); int i=0; for (i=0; i<charsOfStr; i++) CharArray[i]=static_cast<char>(tempStr->ToCharArray()[i]); CharArray[i]=0x00; // Kette abschließen return i; }
-
Umh, ganz schön komliziert. Ich habe ca. 500 Textboxen . Gut, das wäre mit dem globalen Eventhandler zu lösen. Wie ich allerdings vom Rückgabewert(Länge des Arrays), auf meine gewünschten 2 Nachkommastellen kommen soll, ist mir leider jetzt nicht so ganz klar.
Ich würde das also eher gleich in dieser Funktion lösen:
String Misc::StrToCharArray(System::String * tempStr,char* CharArray) { if (tempStr == NULL) return -102001901; // ERROR: instance is missing int charsOfStr=tempStr->get_Length(); int i=0; for (i=0; i<charsOfStr; i++) { CharArray[i]=static_cast<char>(tempStr->ToCharArray()[i]); // String kürzen if(CharArray[i] == "." || (charsOfStr - i) > 2 ) charsOfStr -= i+2; } CharArray[i]=0x00; // Kette abschließen return CharArray.ToString(); //String zurückgeben }
Wäre das so in der Art korrekt(soll hier jetzt nur für den Fall gelten das mehr als 2 Nachkommastellen dran sind)? Für den Fall das eine Zahl keine Nachkommastellen hat, aber xxx,00 angezeigt werden soll muss man sich wohl auch noch was ausdenken.
-
hi!
auf den ersten Blick würde ich vorschlagen die erste for-schleife in ruhe zu lassen und das Kürzen in einer Zweiten zu lösen, also etwa so:
String Misc::StrToCharArray(System::String * tempStr,char* CharArray) { if (tempStr == NULL) return -102001901; // ERROR: instance is missing int charsOfStr=tempStr->get_Length(); int i=0; for (i=0; i<charsOfStr; i++) // Umwandeln in char* { CharArray[i]=static_cast<char>(tempStr->ToCharArray()[i]); } CharArray[i]=0x00; // Kette abschließen // String kürzen bool komma_gefunden = false; for (i=0; i<charsOfStr; i++) { if (CharArray[i] == 0x2e || CharArray[i] == 0x2c) // 0x2e ist der Hex-Ascii-Code für '.', 0x2c = ',' { // Algorithmus zum Kürzen komma_gefunden = true; } } if (!komma_gefunden) { // Manuell Komma anfügen } return CharArray.ToString(); //String zurückgeben }
Das hat den Vorteil, dass du besser Haltepunkte einsetzen kannst und ich vermute, dass es leichter zu verstehen ist wenn mal jemand anders damit arbeitet. Oder du selbst in einem halben Jahr.
Für den Algortihmus hab ich grad keine Zeit.
Hilft dir das weiter? Oder hab ich dich falsch verstanden?
gruß
pAT
EDIT:
Ach ja, bevor das wen irritiert, das "return -102001901" am Anfang ist nur ein Fehlercode
if (tempStr == NULL) return -102001901; // ERROR: instance is missing
Hat also nix mit der Funktion zu tun. also einfach weglassen.
-
Jo, so in der Art. Ich probiers mal bei Gelegenheit aus, zuerst muss ich es hinkriegen für alle Textboxen den OnChange Eventhandler zu definieren, das haut im Moment noch nicht so ganz hin.
-
pocketom schrieb:
Jo, so in der Art. Ich probiers mal bei Gelegenheit aus, zuerst
muss ich es hinkriegen für alle Textboxen den OnChange Eventhandler zu definieren,
das haut im Moment noch nicht so ganz hin.Ich bin kein Freund davon, für X-Tausend Controls das selbe Event abzufangen
und drauf zu reagieren.
Imho ist es schöner, ein neues Control zu erzeugen, dass die gewünschte
Funktionalität bietet:Mach eine neue Klasse, leite die von System::Windows::Forms::TextBox ab
und nenn sie z. B. NumericTextBox.
Dann fangst du das OnChange Event in dieser Klasse ab und klopfst dorten den
Code rein, der aufpasst dass nur Ziffern eingegeben werden.Wenn dann noch unter Tools->Options->Windows Forms Designer->General
das "AutoToolboxPopulate" auf "True" steht, lässt sich die NumericTextBox ganz
doll im Forms Designer verwenden.
-
Hi und erstmal ein frohes Neues!
Nun nachdem die Feiertage rum sind habe ich wieder mit der Problematik beschäftigt. Leider bekomme ich es nicht hin in dem OnLeaveTextBox Eventhandler auf den Text der jeweiligen Textbox zuzugreifen.
Das Ganze sieht im Moment so aus:
void AssignEventHandler(Control ^parent) { for each(Control ^c in parent->Controls) { TextBox ^tb = dynamic_cast<TextBox^>(c); if (tb != nullptr) tb->Leave += gcnew System::EventHandler(this, &MainForm::onLeaveTextBox); else AssignEventHandler(c); } } void onLeaveTextBox(System::Object^ sender, System::EventArgs^ e){this->storeData(); this->updateView();} MainForm(void):DataObj(gcnew XMLDataINOUT),Calc(gcnew Calculations(DataObj)) { InitializeComponent(); AssignEventHandler(this); }
Im Moment dient das ganze nur dazu die Werte sämtlicher Felder neu zu berechnen sobald das geänderte Feld verlassen wird. Das funktioniert soweit ganz gut. Nur wie bekomme ich es nun hin den Text jeder Textbox von der onLeaveTextBox Funktion verändern zu lassen, also auf 2 Nachkommastellen zu kürzen mittels des oben beschriebenen Ansatzes? Habe es über "sender" probiert, das klappte aber garnicht, mir fehlt hierzu einfach noch der nötige Background befürchte ich.
Kann mir irgendwer von Euch kurz auf die Sprünge helfen? Das wäre superklasse
-
was soll den "storeData" und "updateView" sein? das sind die beiden einzigen Zeilen die hier interessant sind...
Auch ist der Code überhaupt nicht ersichtlich, welcher die "Zahlen" wieder in die TextBoxen schreibt...
Du musst es dann schon mit ToString machen ala:double dVal = 10.12; TextBox1->Text = dbl.ToString("0.00");
-
Hi, updateView() und storeData() sind selbstgeschriebene Funktionen in denen den textBoxen entweder berechnete Werte "gesendet" werden(updateView), oder Daten aus den textBoxen gelesen werden. D.h. diese beiden Funktionen sind nur da um die Ansicht zu aktualisieren, allerdings wird da jede textbox einzeln angesprochen. Ich möchte das mit den Nachkommastellen mit möglichst wenig Code für alle auf einmal lösen.
Um die Nachkommastellen auf 2 zu kürzen möchte ich das jedoch nicht für jede der 500 TextBoxen nochmal einzeln machen. Stattdessen möchte ich einfach das der Text beim Onleave Event aus allen Textboxen gelesen, gekürzt und sofort wieder an die jeweilige Textbox zurückgeschrieben wird. Das ganze soll automatisch für alle Textboxen im Projekt gelten, ohne dabei jede gezielt einzeln ansprechen zu müssen.
Was mir also fehlt ist wie ich in der OnLeave Funktion den Text aller Boxen auf einmal korrigieren lasse. Habe es bereits mit text = sender->Text u.Ä. probiert, das haut aber alles nicht hin.
Hoffe das hab ich jetzt verständlicher erklärt, wenn nicht, einfach nochmal nachfragen
-
void onLeaveTextBox(System::Object^ sender, System::EventArgs^ e) { TextBox ^tb = dynamic_cast<TextBox^>(sender); if (tb != nullptr) { double d = double.Parse(tb->Text); tb->Text = d.ToString("0.00"); } }
!?
-
Das isses! Fettes Merci und sorry das ich mal wieder zu kompliziert gedacht habe