String als Variablen-Namen ansprechen
-
Hi,
ich habe da ein kleines Problem dessen Lösung sich schwer googeln lässt, daher frage ich mal hier.
Ich habe auf einem Programm-Tab ca. 30 Textboxen bei denen ich mittels des LostFocus Events prüfen will ob der eingegebene Wert gültig ist. Nun würde es den Code unnötig aufblähen wenn ich dafür 30 LostFocus Events einrichte. Also habe ich ein Event für alle Textboxen. Das sieht etwa so aus:
txtAlter.LostFocus += TextBox_CheckValue; txtGehalt.LostFocus += TextBox_CheckValue; private void TextBox_CheckValue(object sender, RoutedEventArgs e) { TextBox textBox = ((TextBox)sender); checker.Write_Value(textBox.Name.Substring(3), textBox.Text); }
Ich übergebe also z.B. die Strings "Alter" und "25" als Argumente für eine Methode in einer anderen Klasse in der geprüft und geschrieben werden soll. Und da sieht man auch das Problem:
public class Checker { public int Alter { get; set; } public int Gehalt { get; set; } public void Write_Value(string varName, string text) { (Behandle als Variablen-Name)varName = Convert.ToInt32(text); } }
Ich will also den String als Variablen-Namen ansprechen. Ich weiss dass ich das Problem mit einer 30-fachen Verzweigung lösen könnte, würde das aber gern eleganter machen. Weiss wer wie man das casten muss damit das klappt?
Grüsse
Ank
-
Dein Ansatz klingt trotzdem nicht sonderlich optimal. Ich hab schon länger nicht mehr in C# programmiert, aber du kannst doch über die Argumente rausfinden, WELCHE Textbox das Event ausgelöst hast. An deine Überprüfungsklasse übergibst du dann einfach sender, also die Textbox... Und die kann dann alles damit machen!
Und das was du für die umständliche Lösung suchst, heißt vermutlich Reflections - damit hab ich selber aber noch nicht gearbeitet. Aber versuch es anders zu lösen (so wie ichs oben beschrieben habe).
-
hfghfghfgh schrieb:
...aber du kannst doch über die Argumente rausfinden, WELCHE Textbox das Event ausgelöst hast.
Das war nicht das Problem, den Namen der sender-textbox hab ich ja schon über textBox.Name bekommen, ich wollte nur die 30-fache Verzweigung vermeiden.
Aber Du hast mich mit dem Hinweis zu Reflection auf die richtige Spur gebracht, vielen Dank
Und hier der Code dazu:
using System.Reflection; public class Checker { public int Alter { get; set; } public int Gehalt { get; set; } public void Write_Value(string varName, string text) { PropertyInfo prop = typeof(Checker).GetProperty(varName); prop.SetValue(this, Convert.ToInt32(text), null); } }
Ich versteh allerdings nicht wieso du das für umständlich hältst. Ich kann jetzt beliebig viele Textboxen mit schlappen 4 Zeilen Methoden-Code abfragen. Ausserdem lege ich grossen Wert darauf dass Namen von Control-Elementen ausschliesslich in der MainWindow-Klasse benutzt werden (ähnlich dem Drei-Schichten-Modell bei Datenbank-Applikationen, wo sämtliche Datenbank-Befehle im Business-Layer sein müssen).
Grüsse
Ank
-
Reflection ist nicht unbedingt umständlich. Aber auf jedenfall ziemlich langsam, und sonderlich sicher auch nicht (man kann sogar private Members per Reflection setzen).
Man sollte also wirklich gut überlegen ob Reflection hier wirklich nötig ist, oder obs bessere Wege gibt.
-
Anksunamun schrieb:
Ich will also den String als Variablen-Namen ansprechen.
Heißt das auch, dass du in Checker 30 int-Variablen hast oder ist dein Beispiel nur eine vereinfachte Form? Denn dann könntest du die Werte auch in einem Dictionary<string, int> ablegen und den String aus TextBox.Name als Key verwenden.
Ansonsten könnte vielleicht auch http://msdn.microsoft.com/en-us/library/system.windows.forms.control.tag.aspx helfen, die unelegante Reflection-Lösung zu vermeiden.