Eingabeüberprüfung von TextBoxen, Programm soll anhalten und Korrekturwert übernehmen
-
Hallo, ich tu mir etwas schwer bei der Entgegennahme von Eingabedaten. Ich habe eine Eingabemaske mit mehreren Texboxen. Der User muß diese mit Daten füllen, damit das Programm weiter arbeiten kann. Hat er die Daten eingegeben, drückt er einen Button um die Berechnung zu starten. Nun müssen aber zuerst die 10 TextBoxen überprüft werden, ob sie auch wirklich nur numerische Werte beinhalten (habe ich mit .TryParse() gelöst), ansonsten werden die Felder mit Falscheingaben rot gekennzeichnet. Ist das OK werden die Eingaben in eine Klasse übernommen, wo dann noch die Eingabegrenzen geprüft werden. Wenn ich nun eine TextBox nach der anderen in eine gemeinsamen Prüfmethode prüfe, und eine Eingabe außerhalb der EIngabegrenze ist, gebe ich eine Meldung aus ("Eingabe außer Bereich"). Wie schaffe isch es nun, das Programm anzuhalten, damit der User in dieser Textbox den Eingabewert sofort korrigieren kann, ohne gleich die nächste TextBox überprüfen zu wollen? Da gibts doch irgend etwas mit DoApplication() oder so etwas? Hat da jemand eine gute Lösung für?
Ich könnte auch jede TextBox separat prüfen lassen, wenn die TextBox den Focus verliert, finde ich aber nicht so toll, weil ansonsten so viele MEthoden im Hauptprogramm stehen. Außerdem muß ich sowieso prüfen, ob in allen TBX'en was eingegebn worden ist.
GRuß
Moehrle
-
Also es geht dir im Vordergrund darum wie du Fehler bei den Eingabegrenzen handelst?Oder auch darum wie du die Textfelder validierst.Weil Textfelder so validieren das nur Zahlen drinne stehen, wenn zum beispiel "123ns21" eingegeben wurde, geht ganz einfach mit Regex. Damit validierst du alle Textfelder und überprüfst dann.
-
warum ueberlaest du die textboxen nicht und erstellst "IntegerTextBox"en die ein min - max wert haben und auch nur solche eingaben erlaubt?
fuer wpf hab ich das schon lange gemacht da es mir meistens zu mueselig ist die eingaben jedesmal zu ueberpruefen - drum hab ich mir IntegerTextBox und DoubleTextBox gebaut (mit beachtung des landes)
wer interesse hat, kann den code posten
-
Ja bitte, zeig mal her.
-
hier mal das von der integertextbox, double laeuft simultan
in xaml kann man MinValue und MaxValue setzen - Value selber leider (noch) nicht da muss man das Text property selber nehmen
"Text" sowie "Value" beinhaltet dann immer den aktuellen eingegebenen wert - ich persoenlich arbeite nur mit dem Value property
wenn man nichts eingegeben hat ist Value stets 0, MinValue und MaxValue koennen auch null sein um es ungueltig zu machen
die boxen erlauben nur eingaben in der CurrentUICulture (zb das , oder . bei double)der bisher einzigste bekannte bug ist das man in xaml in dem Text propertie was falsches eingeben kann
public class IntegerTextBox : TextBox { public IntegerTextBox() { CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste, null, CanPasteCommand)); } public static readonly DependencyProperty MinValueProperty = DependencyProperty.Register( "MinValue", typeof(int?), typeof(IntegerTextBox)); public int? MinValue { get { return (int?)GetValue(MinValueProperty); } set { SetValue(MinValueProperty, value); } } public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register( "MaxValue", typeof(int?), typeof(IntegerTextBox)); public int? MaxValue { get { return (int?)GetValue(MaxValueProperty); } set { SetValue(MaxValueProperty, value); } } public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof(int), typeof(IntegerTextBox), new PropertyMetadata(new PropertyChangedCallback(ValueChanged))); public int Value { get { string text = (string)GetValue(TextProperty); int value = 0; if (int.TryParse(text, System.Globalization.NumberStyles.Integer, CultureInfo.CurrentUICulture, out value)) return value; else return 0; } set { SetValue(TextProperty, value.ToString(CultureInfo.CurrentUICulture)); } } private static void ValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { IntegerTextBox box = sender as IntegerTextBox; box.Text = ((int)e.NewValue).ToString(CultureInfo.CurrentUICulture); } private bool Parse(TextBox box, string insertText) { string input = box.Text; input = input.Remove(box.SelectionStart, box.SelectionLength); input = input.Insert(box.SelectionStart, insertText); if ((input.Equals("-", StringComparison.Ordinal)) && (MinValue == null || MinValue < 0)) return true; else { int value = 0; if (int.TryParse(input, System.Globalization.NumberStyles.Integer, CultureInfo.CurrentUICulture, out value) && IsValidRange(value)) return true; else return false; } } private void CanPasteCommand(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = false; if (Clipboard.ContainsText()) { if (Parse(sender as TextBox, Clipboard.GetText())) e.CanExecute = true; } e.Handled = true; } protected override void OnPreviewTextInput(TextCompositionEventArgs e) { if (Parse(this, e.Text)) base.OnPreviewTextInput(e); else e.Handled = true; } private bool IsValidRange(int value) { if ((MinValue == null || value >= MinValue) && (MaxValue == null || value <= MaxValue)) return true; return false; } } }
-
Sehr schön Mr Evil.Aber eine Frage habe ich, ich habe folgendes in meiner C# Karriere noch nie gesehen.
public int? MinValue //was macht das ? hier???
-
das bedeutet das ein datentyp auch null sein kann auch wenn es das normalerweise nicht erlaubt
ein normales int, double kann nicht null sein, darum gibt es das "Nuallable<T>" damit kann man solche typen "null-faehig" machen
und das ? hinter dem typen ist eine kurzschreibweisealso
"int?" ist das selbe wie "Nullable<int>"
-
Ahhh alles klar, Joa Nullable<T> sagte mir was, aber die kurzschreibweise nicht. Danke wieder eine Erfahrung reicher.
-
Mr Evil schrieb:
einzigste bekannte bug ist ...
Das ist kein Bug, sondern resultiert daher dass du das Value Property als Wrapper für das DP ValueProperty falsch implementiert hast. Dort darf außer dem GetValue, bzw. SetValue nie was im Get bzw. Set stehen, da dieser Wrapper vollkommen übergangen wird wenn du das Property in XAML benutzt. Deshalb tut deine Validierung dort auch nicht.
Du nutzt auch nicht alle Möglichkeiten die die Dependency Properties dir bieten. Die können was schönes namens Coercion. Du kannst Coercion Callbacks angeben in den Metadaten, in denen du z.B. das "zurechtstutzen" des Eingabewertes auf einen Wert zwischen Minimum und Maximumwert machen kannst.
-
ehm - ne das ist so
das ValueProperty wird im code selber nicht verwendet, das ist schlichtweg ein dispatcher fuer xaml code zum text property, dh "Value" sowie "Text" wird in xaml derzeit nicht validiert
ich koennte das ValueProperty auch weg lassen, nur ich wollte eine konsistenz, das man in xaml sowie in c# immer nur "Value" benutztdas "Value" property ist auch nicht falsch implementiert, es ist lediglich nur ein wrapper fuer c#, fuer xaml wirds nicht verwendet, das weiss ich {o;
also nur nochmal kurz
das depenency property "ValueProperty" ist nur ein vermittler zum "TextProperty"
und das property "Value" ist lediglich ein c# wrapper um "Text" richtig zu lesen und als valides int zu bekommenbekannt ist nur das ich noch eine ueberpruefung braeuchte um "TextProperty" zu validieren
dazu muesste ich es aber mit einem eigenen TextProperty ueberdecken - daher leb ich einfach damit das man in xaml Value sowie Text noch falsch angeben kann, aber sobald man code in c# setzt oder liest passt der wert
-
Wie schaffe isch es nun, das Programm anzuhalten, damit der User in dieser Textbox den Eingabewert sofort korrigieren kann, ohne gleich die nächste TextBox überprüfen zu wollen? Da gibts doch irgend etwas mit DoApplication() oder so etwas? Hat da jemand eine gute Lösung für?
Schreib doch einfach eine Funktion, die das überprüft, die Felder dann kennzeichnet, und dann als rückgabewert die anzahl der fehler zurückgibt.
dann rufst du diese funktion bei z.b. der OnClick-Funktion auf, und zwar so
//Wenn mindestens ein Fehler auftritt, verlasse die OnClick funktion
void OnClick()
{
//wenn keine fehler, mach weiter
if(this.CheckContent() > 0) return;
//Hier das gleiche
if(this.CheckAreaOfContent() > 0) return;this.Berechne();
}
-
@zwergli
ich hab mir mein code nochmal genauer angesehen - das Value aus der xaml nicht benutzt wird hab ich gar nicht gemerkt, da ich es bisher nur ueber c# benutzt hab
wenn ich eine zahl in xaml in der Value angebe, wird es zwar angezeigt, aber verschwindet sobald ich in das feld klicke
ich vermute das liegt daran das ich die funktion zu sehr missbraucht habeich werds vermutlich so machen das ich das ValueProperty entferne (benutz ich eh nirgends) und irgendwie versuch das TextProperty zu validieren
dann kann man mit c# weiterhin mit "Value" arbeiten, nur in xaml ist dann "Text" zu verwenden statt Value - denn sonst haette ich n problem die propertys in sync zu halten