Каков наилучший способ очистки всех элементов управления на форме С#?
Я помню, как кто-то спрашивал что-то в этих строках некоторое время назад, но я сделал поиск и ничего не нашел.
Я пытаюсь найти самый чистый способ очистить все элементы управления формы до их значений по умолчанию (например, очистить текстовые поля, снять флажки).
Как бы вы это сделали?
Ответы
Ответ 1
То, что я придумал до сих пор, выглядит примерно так:
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>();
В настоящий момент он будет обрабатывать только элементы верхнего уровня и не будет выкапывать через групповые панели и панели.
Ответ 2
Я знаю его старый вопрос, но только мои 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);
Вы можете расширить его для других типов элементов управления. Вам просто нужно бросить его.
Ответ 3
Вы можете выполнить цикл для управления
foreach (Control ctrl in this)
{
if(ctrl is TextBox)
(ctrl as TextBox).Clear();
}
Ответ 4
Я голосовал за решение Nathan, но хотел добавить немного больше, чем может обработать комментарий.
На самом деле он очень хорош, но я думаю, что лучшее решение будет включать подклассификацию каждого из типов управления, которые вы могли бы добавить, прежде чем добавлять их в графический интерфейс. Пусть все они реализуют интерфейс "Clearable" или что-то в этом роде (я программист Java, но концепция должна быть там), а затем перебираем его как коллекцию "Clearable" объектов, вызывая единственный метод .clear() на каждом
Именно так GUI действительно нужно делать в OO-системе. Это упростит ваш код в будущем - почти слишком легко, вы будете в шоке.
Изменить: (за комментарий Nathan об изменении существующих элементов управления)
Возможно, вы могли бы создать классы "Контейнер", которые ссылаются на ваш элемент управления (по одному для каждого типа управления). В цикле, подобном настроенному в вашем ответе, вы можете создать экземпляр правильного контейнера, поместить реальный контроль внутри контейнера и сохранить контейнер в коллекции.
Таким образом вы вернетесь к итерации по коллекции.
Это будет хорошее простое решение, которое не намного сложнее, чем предлагаемое вами, но бесконечно более расширяемое.
Ответ 5
Вышеупомянутые решения, похоже, игнорируют вложенные элементы управления.
Может потребоваться рекурсивная функция, такая как:
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), по набору производных элементов управления сократит длину этой функции, но потребует больше работы над каждым элементом управления.
Ответ 6
Вот то же самое, что я предложил в своем первом ответе, но в VB, пока мы не получим VB10, это лучшее, что мы можем сделать в VB, потому что оно не поддерживает не возвращающие функции в lambdas:
Решение 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.
Ответ 7
private void FormReset() { ViewState.Clear(); Response.Redirect(Request.Url.AbsoluteUri.ToString()); }
Ответ 8
Ниже приведены методы, которые я использую для очистки текста от элемента типа, который реализует 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;
}
}