Каков наилучший способ очистить все элементы управления в форме C #? - PullRequest
14 голосов
/ 18 ноября 2008

Я помню, что видел, как кто-то спрашивал что-то подобное некоторое время назад, но я провел поиск и ничего не смог найти.

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

Как бы вы поступили об этом?

Ответы [ 8 ]

17 голосов
/ 18 ноября 2008

То, что я до сих пор придумал, примерно так:

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

РЕДАКТИРОВАТЬ: я только что добавил общий метод ClearControls, который очистит все элементы управления этого типа, который может быть вызван так:

this.Controls.ClearControls<TextBox>();

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

3 голосов
/ 23 октября 2012

Я знаю, что это старый вопрос, но только мои 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);

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

2 голосов
/ 18 ноября 2008

Вот то же самое, что я предложил в своем первом ответе, но в 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.

2 голосов
/ 18 ноября 2008

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

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

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 (как предложено Биллом К), на наборе производных элементов управления сократит длину этой функции, но потребует дополнительной работы над каждым элементом управления.

2 голосов
/ 18 ноября 2008

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

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

Вот как в действительности нужно создавать GUI в ОО-системе. Это сделает ваш код легко расширяемым в будущем - почти слишком простым, вы будете шокированы.

Редактировать: (за комментарий Натана о том, чтобы не изменять существующие элементы управления)

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

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

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

2 голосов
/ 18 ноября 2008

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

foreach (Control ctrl in this)
{
    if(ctrl is TextBox)
        (ctrl as TextBox).Clear();
}
1 голос
/ 12 января 2011

приватный void FormReset () { ViewState.Clear (); Response.Redirect (Request.Url.AbsoluteUri.ToString ()); }

0 голосов
/ 18 ноября 2008

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

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

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

Примерно так:

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

Метод Clear предназначен для страницы или мастер-страницы. Тип коллекции контроля может отличаться. то есть. Форма, 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;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...