簡體   English   中英

清除C#表單上所有控件的最佳方法是什么?

[英]What is the best way to clear all controls on a form C#?

我記得有一段時間以前看到有人問過這些問題,但是我做了搜索而找不到任何東西。

我正在嘗試用最干凈的方法將表單上的所有控件清除回默認值(例如,清除文本框,取消選中復選框)。

你會怎么做?

到目前為止我想出的是這樣的:

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

目前它只處理頂級控件,不會通過組框和面板進行挖掘。

我知道這是一個老問題但只是我的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);

您可以將其擴展為其他類型的控件。 你只需要施展它。

你可以循環控制

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

我投票贊成了Nathan的解決方案,但想補充一點,而不是評論可以處理。

他實際上非常好,但我認為最好的解決方案是在將它們添加到GUI之前對每個可能添加的控件類型進行子類化。 讓他們都實現一個“可清除”或類似的接口(我是一個java程序員,但概念應該在那里),然后迭代它作為“可清除”對象的集合,調用唯一的方法.clear()在每一個上

這就是如何在OO系統中完成GUI。 這將使您的代碼在將來易於擴展 - 幾乎太容易了,您會感到震驚。

編輯:(根據內森關於不改變現有控制的評論)

也許你可以創建引用你的控件的“容器”類(每種類型的控件一個)。 在您在答案中設置的循環中,您可以實例化正確的容器,將實際控件放在容器中並將容器存儲在集合中。

這樣你就可以重新迭代一個集合了。

這將是一個很好的簡單解決方案,並不比您建議的解決方案復雜得多,但可擴展性更高。

上述解決方案似乎忽略了嵌套控件。

可能需要遞歸函數,例如:

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(如Bill K所建議的)之類的接口將減少該函數的長度,但需要對每個控件進行更多的工作。

這是我在第一個答案中提出的相同的東西,但在VB中,直到我們得到VB10,這是我們在VB中可以做的最好的,因為它不支持lambda中的非返回函數:

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中做同樣的事情。

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

下面是我用從一個類型的控制實現ITextBox明文的方法。

我注意到在示例中設置了默認的布爾值。 我相信你可以修改它來設置布爾組件的默認值。

將Clear方法傳遞給控件類型(TextBox,Label ...等)和控件集合,它將清除實現ITextBox的控件中的所有文本。

像這樣的東西:

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

Clear方法適用於頁面或母版頁。 控件集合類型可能有所不同。 即。 Form,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;
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM