Entwickler-Ecke
WPF / Silverlight - Problem beim Leeren aller Textboxen
mocede - Mo 29.12.14 19:29
Titel: Problem beim Leeren aller Textboxen
Hallo,
ich möchte in einer WPF Anwendung mehrere Textboxen innerhalb einer Groupbox leeren.
Sicherlich kann man jetzt jede Textbox einzeln wie folgt leeren:
C#-Quelltext
1: 2: 3:
| txt_1.Clear(); txt_2.Clear(); ... |
Hierbei ergibt sich aber das Problem, dass dies bei besonders vielen Textboxen den Quelltext aufbläht. Schöner wäre da eine ausgereiftere Lösung.
Auf der Suche im Netz habe ich mehrere Lösungen gefunden, die alle grundlegend erstmal gleich aussehen. Die ergoogelte Lösung sieht wie folgt aus:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| private void btn_Clear_Click(object sender, RoutedEventArgs e) { ClearTextBoxes(this.Controls); }
private void ClearTextBoxes(Control.ControlCollection cc) { foreach (Control ctrl in cc) { TextBox tb = ctrl as TextBox;
if (tb != null) tb.Text = ""; else ClearTextBoxes(ctrl.Controls); } } |
Mein Problem ist, dass ich die Lösung an den entscheidenten Punkten nicht verstehe und sie darum auch nicht zum Laufen bekomme.
Mir ist klar, dass ich beim Klick auf den Button
btn_Clear die Methode zum Löschen der Textboxen names
ClearTextBoxesaufrufe. Doch was ist
Control.ControlCollection cc für ein Übergabeparameter?
In der Methode starte ich nun eine foreach-Schleife, welche mir die Textboxen "" setzt, sofern diese nicht leer sind. Doch was hat es mit der Schleifenbedingung (Control ctrl in cc) auf sich? Und was bedeuted das hier genau:
C#-Quelltext
1:
| TextBox tb = ctrl as TextBox; |
Beim Compilieren bekomme ich die Fehlermeldung
"Der Typname 'ControlCollection' ist im Typ 'System.Windows.Controls.Control" nicht vorhanden"
Das sollte doch aber bei Einbinden von
System.Windows.Controls; mittels
using der Fall sein, oder?
Kann mir jemand bitte helfen den Quelltext zum Laufen zu bekommen?
Moderiert von
Th69: Topic aus C# - Die Sprache verschoben am Mo 29.12.2014 um 20:10
C# - Mo 29.12.14 21:03
Hallo,
also die
ControlCollection kommt meines wissens aus WinForms, deshalb kannst du sie auch nicht in WPF verwenden. Du könntest statt dessen
UIElementCollection oder ein Root Element, z.B.
Panel benutzen.
Dann sähe der Code so aus:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| private void ClearTextBoxes(Panel rootElement) { if (rootElement == null) return;
foreach (UIElement el in rootElement.Children) { TextBox tb = el as TextBox;
if (tb != null) tb.Clear(); else ClearTextBoxes(el as Panel); } } |
Das Schlüsselwort
as führt dabei eine Konvertierung in den Zieldatentyp durch (im ersten Fall wäre der Zieldatentyp
TextBox, im Zweiten
Panel). Kann das Objekt nicht konvertiert werden, wird
null zurück gegeben.
Der
else-Block enthält eine Rekursion. So wird sichergestellt, dass alle weiteren Unterelemente auch gelöscht werden, wenn sie TextBoxen sind.
Sagen wir du hast so eine Struktur:
XML-Daten
1: 2: 3: 4: 5: 6: 7: 8:
| <Grid Name="RootGrid"> <TextBox /> <TextBox /> <Grid Name="SubGrid"> <TextBox /> <TextBox /> </Grid> </Grid> |
C#-Quelltext
1:
| ClearTextBoxes(RootGrid); |
dann sorgt die Rekursion dafür, dass auch die TextBoxen in
SubGrid gelöscht werden.
mocede - Di 30.12.14 00:50
Hallo C#,
danke für deine Antwort! In der Tat löst dein Code mein Problem, vielen Dank dafür!
Ich glaube von alleine hätte ich das niemals hinbekommen. Einhundertprozentig verstehe ich zwar immer noch nicht was da passiert, aber in diesem Fall geb ich mich mal damit zufrieden das es funktioniert. Leider fehlt mir der Hintergrund zu diesen Panel und UIElementen.
Was mir allerdings auffällt ist, dass das Leeren der TextBoxen nur klappt, wenn diese von bestimmten Steuerelementen "ummantelt" sind, korrekt? Wenn ich den Namen einer GroupBox angebe, klappt das Leeren nicht mehr. Stackpaneles sind dagegen kein Problem. Der Compiler sagt mir, dass ein Problem mit der Konvertierung vorliegt.
Lösen sollte sich das im Falle eines Falles eigentlich ziemlich einfach, indem ich bei solchen Problemen einfach nochmal ein zusammenfassendes, quasi unsichtbares Grid ziehe und dieses dann halt über deine Methode leeren lasse...
Vielen Dank für deine Hilfe!
C# - Di 30.12.14 01:31
Hallo,
kein Problem. Ich habe die Methode nochmal etwas abgeändert, sodass es jetzt auch mit der GroupBox geht:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| private void ClearTextBoxes(UIElement rootElement) { if (rootElement == null) return;
Panel panel = rootElement as Panel; ContentControl cc = rootElement as ContentControl;
if (panel != null) { foreach (UIElement el in panel.Children) { TextBox tb = el as TextBox;
if (tb != null) tb.Clear(); else ClearTextBoxes(el); } } else if (cc != null) { TextBox tb = cc.Content as TextBox;
if (tb != null) tb.Clear(); else ClearTextBoxes(cc.Content as UIElement); } } |
Im Prinzip funktioniert das ganze so:
Zuerst wird versucht, dass übergebene UIElement weiter zu spezifizieren, sodass man auf die
Children- oder
Content-Eigenschaft zugreifen kann. Anschließend wird geprüft, ob das entsprechende Child bzw. der entsprechende Content eine TextBox ist. Ist das der Fall, wird die TextBox geleert. Wenn das nicht der Fall ist, ruft die Methode sich selbst auf (
ClearTextBoxes(el); bzw.
ClearTextBoxes(cc.Content as UIElement);). Das führt dazu, dass dann die Kinder des UIElements (
Children) auch nochmal untersucht werden. So findet man auch TextBoxen, die z.B. in 4 Panels verschachtelt sind.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!