2008-11-18 2 views
14

Я помню, как кто-то спрашивал что-то в этих строках некоторое время назад, но я сделал поиск и ничего не нашел.Каков наилучший способ очистки всех элементов управления на форме C#?

Я пытаюсь найти самый чистый способ очистить все элементы управления формы до их значений по умолчанию (например, очистить текстовые поля, снять флажки).

Как бы вы это сделали?

ответ

17

То, что я придумал до сих пор что-то вроде этого:

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); 
      } 
     }  

    } 

} 

Теперь вы можете просто вызвать метод расширения ClearControls как это:

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

EDIT: Я только что добавили общий метод ClearControls, который очистит все элементы управления этого типа, которые могут быть вызваны следующим образом:

this.Controls.ClearControls<TextBox>(); 

В настоящий момент он будет обрабатывать только элементы управления верхнего уровня и не будет выкапывать групповые группы и панели.

+0

увлекательный пример! Благодарю. – BillW 2009-11-28 13:22:59

2

Вы можете петля для управления

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

Я делал такой подход, но я хотел найти что-то немного меньше, если бы ... далее. – 2008-11-18 01:06:32

2

Я голосовал за решение Натана, но хотел бы добавить немного больше, чем комментарий может справиться.

Его на самом деле очень хорошо, но я думаю, что лучшее решение будет включать в себя суб-классификацию каждого из типов управления, которые вы могли бы добавить, прежде чем добавлять их в графический интерфейс. Пусть все они реализуют интерфейс «Clearable» или что-то в этом роде (я программист Java, но концепция должна быть там), а затем перебираем его как коллекцию «Clearable» объектов, вызывая единственный метод .clear() на каждом

Вот как следует делать GUI в системе OO. Это упростит ваш код в будущем - почти слишком легко, вы будете в шоке.

Edit: (за комментарий Натана о не изменяя существующие элементы управления)

Может быть, вы могли бы создать «контейнер» классы, которые ссылаются на элемент управления (по одному для каждого типа управления). В цикле, подобном настроенному в вашем ответе, вы можете создать экземпляр правильного контейнера, поместить реальный контроль внутри контейнера и сохранить контейнер в коллекции.

Таким образом, вы вернетесь к итерации по коллекции.

Это будет хорошее простое решение, которое не намного сложнее, чем тот, который вы предложили, но бесконечно более расширяемый.

+0

Да + миллион. Всегда, всегда, всегда подклассируйте каждый элемент управления, прежде чем добавлять его в свой проект. Это позволяет вам многое изменить в дальнейшем. – 2008-11-18 01:24:49

+0

Я думал обо всем подклассе, но я просто реорганизовал старый проект, и я не хотел повторять интерфейс. В будущих проектах я буду подклассифицировать все. – 2008-11-18 01:34:42

0

Ниже приведены методы, которые я использую для очистки текста от типа управления, которое реализует ITextBox.

Я заметил, что в примере по умолчанию установлены значения булина. Я уверен, что вы можете изменить его, чтобы установить значения по умолчанию для булевых компонентов.

Передайте методу Clear метод управления (TextBox, Label ... и т. Д.) И коллекцию управления, и он очистит весь текст от элементов управления, реализующих ITextBox.

Что-то вроде этого:

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

Ясный метод предназначен для страницы или Masterpage. Тип коллекции управления может отличаться. то есть. Форма, ContentPlaceHolder .. и т. Д.

 /// <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

Вышеупомянутые решения, похоже, игнорируют вложенные элементы управления.

Рекурсивная функция может потребоваться, например, как:

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) 
    } 
    } 
} 

Вы не хотите, чтобы просто очистить свойство Text без проверки типа элементов управления.

Внедрение интерфейса, такого как IClearable (как предложено Биллом K), по набору производных элементов управления сократит длину этой функции, но потребует больше работы над каждым элементом управления.

2

Вот то же самое, что я предложил в мой первый ответ, но в VB, пока мы не получим VB10 это лучшее, что мы можем сделать в VB, так как он не поддерживает удобства функции, возвращающие в лямбдах:

VB Решение:

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 

Призвание:

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

Я просто размещая это здесь, чтобы люди могли видеть, как делать то же самое в VB.

1

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

3

Я знаю его старый вопрос, но только мои 2 цента дюйма Это вспомогательный класс, который я использую для очистки формы.

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; 
       } 
      } 
     } 
    } 
} 

И я вызываю метод из любой формы, такой как передача объекта формы в качестве параметра.

Helper.ClearFormControls(this); 

Вы можете расширить его для других типов элементов управления. Вам просто нужно бросить его.

Смежные вопросы