Что лучший способ состоит в том, чтобы очистить все средства управления на форме C#?

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
14
задан BDawg 2 April 2015 в 12:23
поделиться

6 ответов

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

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

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

17
ответ дан 24 October 2019 в 05:06
поделиться

Можно циклично выполниться для управления

foreach (Control ctrl in this)
{
    if(ctrl is TextBox)
        (ctrl as TextBox).Clear();
}
2
ответ дан 24 October 2019 в 05:06
поделиться

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

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

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

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

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

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

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

2
ответ дан 24 October 2019 в 05:06
поделиться

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

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

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

Вы не хотите просто очищать текстовое свойство, не проверяя тип средств управления.

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

2
ответ дан 24 October 2019 в 05:06
поделиться

Вот то же самое, которое я предложил в своем первом ответе, но в 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
ответ дан 24 October 2019 в 05:06
поделиться

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

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

Передача Четкий метод тип управления (TextBox, Маркировка... и т.д.) и набор управления, и это очистит весь текст от средств управления та реализация ITextBox.

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

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

Четкий метод предназначен для Page или 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;
        }
    }
0
ответ дан 24 October 2019 в 05:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: