Как лучше всего очистить все элементы управления в форме C#?

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
16
0
45 702
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Ответ принят как подходящий

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

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

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

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

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

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

Nathan W 18.11.2008 04:06

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

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

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

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

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

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

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

Да + миллион. Всегда, всегда, всегда подклассифицируйте каждый элемент управления перед добавлением его в свой проект. Это позволяет вам намного проще изменить вещи позже.

Cade Roux 18.11.2008 04:24

Я думал обо всем, что касается подкласса, но я просто реорганизовывал старый проект, и мне не хотелось переделывать пользовательский интерфейс. В будущих проектах я буду подклассифицировать все.

Nathan W 18.11.2008 04:34

@Bill Я учту ваши предложения.

Nathan W 18.11.2008 04:56

Ниже приведены методы, которые я использую для очистки текста от элемента управления тип, реализующего 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;
        }
    }

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

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

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

Представленное мной решение будет включать вложенные элементы управления.

Nathan W 18.11.2008 06:41

Натан, это интересное решение. Вложенный аспект кода не сразу бросался в глаза при взгляде на код, поэтому я этого не заметил.

benPearce 18.11.2008 07:06

Как бы вы вызывали метод из кода программной части?

SearchForKnowledge 14.04.2015 16:09

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

частная недействительность FormReset () { ViewState.Clear (); Response.Redirect (Request.Url.AbsoluteUri.ToString ()); }

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

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

Другие вопросы по теме