2008-11-18 5 views
14

Ich erinnere mich, dass jemand vor einiger Zeit etwas in dieser Richtung gefragt hat, aber ich habe eine Suche gemacht und konnte nichts finden.Was ist der beste Weg, um alle Steuerelemente in einem Formular C# zu löschen?

Ich versuche, die sauberste Möglichkeit zu finden, alle Steuerelemente in einem Formular auf ihre Standardwerte zurückzusetzen (z. B. leere Textfelder, Kontrollkästchen deaktivieren).

Wie würden Sie darüber gehen?

Antwort

17

Was ich mit so weit kommen haben, ist so etwas wie dieses:

public static class extenstions 
{ 
    private static Dictionary<Type, Action<Control>> controldefaults = new Dictionary<Type, Action<Control>>() { 
      {typeof(TextBox), c => ((TextBox)c).Clear()}, 
      {typeof(CheckBox), c => ((CheckBox)c).Checked = false}, 
      {typeof(ListBox), c => ((ListBox)c).Items.Clear()}, 
      {typeof(RadioButton), c => ((RadioButton)c).Checked = false}, 
      {typeof(GroupBox), c => ((GroupBox)c).Controls.ClearControls()}, 
      {typeof(Panel), c => ((Panel)c).Controls.ClearControls()} 
    }; 

    private static void FindAndInvoke(Type type, Control control) 
    { 
     if (controldefaults.ContainsKey(type)) { 
      controldefaults[type].Invoke(control); 
     } 
    } 

    public static void ClearControls(this Control.ControlCollection controls) 
    { 
     foreach (Control control in controls) 
     { 
      FindAndInvoke(control.GetType(), control); 
     } 
    } 

    public static void ClearControls<T>(this Control.ControlCollection controls) where T : class 
    { 
     if (!controldefaults.ContainsKey(typeof(T))) return; 

     foreach (Control control in controls) 
     { 
      if (control.GetType().Equals(typeof(T))) 
      { 
       FindAndInvoke(typeof(T), control); 
      } 
     }  

    } 

} 

Jetzt können Sie nur die Erweiterung Methode ClearControls wie folgt aufrufen:

private void button1_Click(object sender, EventArgs e) 
    { 
     this.Controls.ClearControls(); 
    } 

EDIT: Ich habe soeben ein generische ClearControls-Methode, die alle Steuerelemente dieses Typs löscht, die wie folgt aufgerufen werden können:

Im Moment wird es nur Top-Level-Kontrollen behandeln und nicht durch Gruppenboxen und Panels graben.

+0

ein faszinierendes Beispiel! Vielen Dank. – BillW

2

Sie können Schleife zur Steuerung

foreach (Control ctrl in this) 
{ 
    if(ctrl is TextBox) 
     (ctrl as TextBox).Clear(); 
} 
+0

Ich machte diese Art von Ansatz, aber ich wollte etwas ein bisschen weniger finden, wenn ... dann ..else Basis. –

2

ich für Nathans Lösung gestimmt, aber ich wollte ein bisschen mehr hinzuzufügen als ein Kommentar verarbeiten kann.

Er ist eigentlich sehr gut, aber ich denke, die beste Lösung würde Sub-Classing jedes der Steuerelementtypen, die Sie hinzufügen, bevor Sie sie in der GUI hinzufügen. Haben sie alle eine Schnittstelle "Clearable" oder so ähnlich implementieren (ich bin ein Java-Programmierer, aber das Konzept sollte da sein), dann iterieren als eine Sammlung von "Clearable" -Objekte, Aufruf der einzigen Methode .clear() auf jedem

Dies ist, wie GUIs wirklich in einem OO-System getan werden sollte. Dadurch wird Ihr Code in der Zukunft einfach zu erweitern sein - fast zu einfach, Sie werden schockiert sein.

Edit: (pro Nathans Kommentar über nicht vorhandene Kontrollen zu ändern)

Vielleicht könnten Sie „Container“ Klassen erstellen, die Ihre Steuerung (einen für jede Art der Steuerung) verweisen. In einer Schleife wie der, die Sie in Ihrer Antwort eingerichtet haben, können Sie den richtigen Container instanziieren, das echte Steuerelement in den Container einfügen und den Container in einer Sammlung speichern.

Auf diese Weise sind Sie wieder über eine Sammlung iterieren.

Dies wäre eine gute einfache Lösung, die nicht viel komplexer ist als die, die Sie vorgeschlagen haben, aber unendlich erweiterbar.

+0

Ja + Millionen. Unterteilen Sie jedes Steuerelement immer immer, bevor Sie es zu Ihrem Projekt hinzufügen. So können Sie die Dinge später viel einfacher ändern. –

+0

Ich dachte über die ganze Sub-Klasse-Sache nach, aber ich war gerade dabei, ein altes Projekt zu refactorieren und ich wollte die Benutzeroberfläche nicht noch einmal machen müssen. In zukünftigen Projekten werde ich alles unterteilen. –

+0

@Bill Ich werde Ihre Vorschläge berücksichtigen. –

0

Unten sind Methoden, die ich verwende, um Text von einem Typ Steuerelement zu löschen, das ITextBox implementiert.

Ich bemerkte, dass im Beispiel Standard Boolean Werte gesetzt sind. Ich bin sicher, dass Sie es ändern können, um Standardwerte von booleschen Komponenten festzulegen.

Übergeben Sie die Clear-Methode einen Steuerelementtyp (TextBox, Label ... usw.) und eine Steuerelementauflistung, und es wird den gesamten Text von Steuerelementen löschen, die ITextBox implementieren.

Etwas wie folgt aus:

//Clears the textboxes 
WebControlUtilities.ClearControls<TextBox>(myPanel.Controls); 

Die Clear-Methode ist für eine Seite oder MasterpaDE gemeint. Der Kontrollsammeltyp kann variieren. dh. Form, ContentPlaceHolder .. usw.

 /// <summary> 
    /// Clears Text from Controls...ie TextBox, Label, anything that implements ITextBox 
    /// </summary> 
    /// <typeparam name="T">Collection Type, ie. ContentPlaceHolder..</typeparam> 
    /// <typeparam name="C">ie TextBox, Label, anything that implements ITextBox</typeparam> 
    /// <param name="controls"></param> 
    public static void Clear<T, C>(ControlCollection controls) 
     where C : ITextControl 
     where T : Control 
    { 
     IEnumerable<T> placeHolders = controls.OfType<T>(); 
     List<T> holders = placeHolders.ToList(); 

     foreach (T holder in holders) 
     { 
      IEnumerable<C> enumBoxes = holder.Controls.OfType<C>(); 
      List<C> boxes = enumBoxes.ToList(); 

      foreach (C box in boxes) 
      { 
       box.Text = string.Empty; 
      } 
     } 
    } 

    /// <summary> 
    /// Clears the text from control. 
    /// </summary> 
    /// <typeparam name="C"></typeparam> 
    /// <param name="controls">The controls.</param> 
    public static void ClearControls<C>(ControlCollection controls) where C : ITextControl 
    { 
     IEnumerable<C> enumBoxes = controls.OfType<C>(); 
     List<C> boxes = enumBoxes.ToList(); 

     foreach (C box in boxes) 
     { 
      box.Text = string.Empty; 
     } 
    } 
2

Die obigen Lösungen scheinen verschachtelte Steuerelemente zu ignorieren.

Eine rekursive Funktion kann erforderlich sein, wie zum Beispiel:

public void ClearControl(Control control) 
{ 
    TextBox tb = control as TextBox; 
    if (tb != null) 
    { 
    tb.Text = String.Empty; 
    } 
    // repeat for combobox, listbox, checkbox and any other controls you want to clear 
    if (control.HasChildren) 
    { 
    foreach(Control child in control.Controls) 
    { 
     ClearControl(child) 
    } 
    } 
} 

Sie wollen nicht nur die Eigenschaft Text löschen, ohne die Kontrollen Typen zu überprüfen. Das Implementieren einer Schnittstelle, wie IClearable (wie von Bill K vorgeschlagen), auf einer Menge abgeleiteter Steuerelemente würde die Länge dieser Funktion reduzieren, erfordert jedoch mehr Arbeit an jedem Steuerelement. Hier

+0

Die von mir präsentierte Lösung enthält verschachtelte Steuerelemente. –

+0

Nathan, das ist eine interessante Lösung. Der verschachtelte Aspekt des Codes war beim Betrachten des Codes nicht sofort ersichtlich, also habe ich das nicht bemerkt. – benPearce

+0

Ja, es ist ein wenig, aber versteckt, aber hey, es funktioniert gut –

2

ist die gleiche Sache, die ich in meiner ersten Antwort vorgeschlagen, aber in VB, bis wir VB10 bekommen dies die beste ist, die wir in VB tun können, weil sie nicht ohne Rückkehr Funktionen in lambdas unterstützt:

VB Lösung:

Public Module Extension 
    Private Sub ClearTextBox(ByVal T As TextBox) 
     T.Clear() 
    End Sub 

    Private Sub ClearCheckBox(ByVal T As CheckBox) 
     T.Checked = False 
    End Sub 

    Private Sub ClearListBox(ByVal T As ListBox) 
     T.Items.Clear() 
    End Sub 

    Private Sub ClearGroupbox(ByVal T As GroupBox) 
     T.Controls.ClearControls() 
    End Sub 

    <Runtime.CompilerServices.Extension()> _ 
    Public Sub ClearControls(ByVal Controls As ControlCollection) 
     For Each Control In Controls 
      If ControlDefaults.ContainsKey(Control.GetType()) Then 
       ControlDefaults(Control.GetType()).Invoke(Control) 
      End If 
     Next 
    End Sub 

    Private _ControlDefaults As Dictionary(Of Type, Action(Of Control)) 
    Private ReadOnly Property ControlDefaults() As Dictionary(Of Type, Action(Of Control)) 
     Get 
      If (_ControlDefaults Is Nothing) Then 
       _ControlDefaults = New Dictionary(Of Type, Action(Of Control)) 
       _ControlDefaults.Add(GetType(TextBox), AddressOf ClearTextBox) 
       _ControlDefaults.Add(GetType(CheckBox), AddressOf ClearCheckBox) 
       _ControlDefaults.Add(GetType(ListBox), AddressOf ClearListBox) 
       _ControlDefaults.Add(GetType(GroupBox), AddressOf ClearGroupbox) 
      End If 
      Return _ControlDefaults 
     End Get 
    End Property 

End Module 

Berufung:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
     Me.Controls.ClearControls() 
    End Sub 

ich bin einfach posten Sie das hier, damit die Leute sehen können, wie sie in VB dasselbe machen.

1

private void FormReset() { ViewState.Clear(); Response.Redirect (Request.Url.AbsoluteUri.ToString()); }

3

Ich weiß es ist eine alte Frage, aber nur meine 2 Cent in. Dies ist eine Helfer-Klasse, die ich für das Formular Clearing verwenden.

using System; 
using System.Windows.Forms; 

namespace FormClearing 
{ 
    class Helper 
    { 
     public static void ClearFormControls(Form form) 
     { 
      foreach (Control control in form.Controls) 
      { 
       if (control is TextBox) 
       { 
        TextBox txtbox = (TextBox)control; 
        txtbox.Text = string.Empty; 
       } 
       else if(control is CheckBox) 
       { 
        CheckBox chkbox = (CheckBox)control; 
        chkbox.Checked = false; 
       } 
       else if (control is RadioButton) 
       { 
        RadioButton rdbtn = (RadioButton)control; 
        rdbtn.Checked = false; 
       } 
       else if (control is DateTimePicker) 
       { 
        DateTimePicker dtp = (DateTimePicker)control; 
        dtp.Value = DateTime.Now; 
       } 
      } 
     } 
    } 
} 

Und ich rufe die Methode von jeder Form wie diese ein Formularobjekt als Parameter übergeben.

Helper.ClearFormControls(this); 

Sie können es für andere Arten von Steuerungen erweitern. Sie müssen es nur werfen.

Verwandte Themen