2008-11-18 39 views
14

Tôi nhớ khi thấy ai đó hỏi điều gì đó dọc theo những dòng này trước đây nhưng tôi đã thực hiện tìm kiếm và không thể tìm thấy bất cứ điều gì.Cách tốt nhất để xóa tất cả các điều khiển trên biểu mẫu C# là gì?

Tôi đang cố gắng tìm ra cách sạch nhất để xóa tất cả các điều khiển trên biểu mẫu về mặc định của chúng (ví dụ: hộp văn bản rõ ràng, bỏ chọn hộp kiểm).

Bạn sẽ giải quyết vấn đề này bằng cách nào?

Trả lời

17

Những gì tôi đã đưa ra cho đến nay là một cái gì đó như thế này:

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

    } 

} 

Bây giờ bạn có thể chỉ cần gọi ClearControls phương pháp khuyến nông như thế này:

private void button1_Click(object sender, EventArgs e) 
    { 
     this.Controls.ClearControls(); 
    } 

EDIT: Tôi vừa bổ sung thêm một phương pháp ClearControls chung sẽ xóa tất cả các điều khiển của loại đó, có thể được gọi như sau:

this.Controls.ClearControls<TextBox>(); 

Hiện tại, nó sẽ chỉ xử lý các điều khiển mức cao nhất và sẽ không đào sâu qua các hộp nhóm và bảng điều khiển.

+0

một ví dụ hấp dẫn! cảm ơn. – BillW

2

Bạn có thể lặp để kiểm soát

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

Tôi đã thực hiện kiểu tiếp cận này nhưng tôi muốn tìm thứ gì đó hơi ít hơn một chút nếu..đây..xây dựng cơ sở. –

2

Tôi đã bỏ phiếu cho giải pháp của Nathan, nhưng muốn thêm một chút so với một lời nhận xét có thể xử lý.

Thực sự là rất tốt, nhưng tôi nghĩ giải pháp tốt nhất sẽ liên quan đến việc phân loại từng loại điều khiển mà bạn có thể thêm trước khi thêm chúng vào GUI. Có tất cả chúng thực hiện một giao diện "Clearable" hoặc một cái gì đó như thế (tôi là một lập trình java, nhưng khái niệm nên có), sau đó iterate trên nó như là một bộ sưu tập của "Clearable" đối tượng, gọi phương pháp duy nhất. Rõ ràng() trên mỗi

Đây là cách GUI thực sự nên được thực hiện trong hệ thống OO. Điều này sẽ làm cho mã của bạn dễ dàng mở rộng trong tương lai - gần như quá dễ dàng, bạn sẽ bị sốc.

Edit: (mỗi bình luận của Nathan về việc không thay đổi điều khiển hiện có)

lẽ bạn có thể tạo ra "container" lớp học mà tham khảo kiểm soát của bạn (một cho từng loại đối chứng). Trong một vòng lặp giống như thiết bị bạn đã thiết lập trong câu trả lời, bạn có thể tạo nhanh vùng chứa chính xác, đặt điều khiển thực bên trong vùng chứa và lưu trữ vùng chứa trong bộ sưu tập.

Bằng cách đó bạn quay lại để lặp qua bộ sưu tập.

Đây sẽ là một giải pháp đơn giản, không phức tạp hơn nhiều so với giải pháp bạn đề xuất, nhưng vô cùng mở rộng hơn.

+0

Có + triệu. Luôn luôn, luôn luôn, luôn luôn phân lớp mọi kiểm soát trước khi thêm nó vào dự án của bạn. Nó cho phép bạn thay đổi mọi thứ dễ dàng hơn nhiều sau này. –

+0

Tôi đã nghĩ về toàn bộ lớp phụ nhưng tôi chỉ đang tái cấu trúc một dự án cũ và tôi không muốn phải làm lại giao diện người dùng. Trong các dự án tương lai, tôi sẽ phụ mọi thứ. –

+0

@Chúng tôi sẽ xem xét đề xuất của bạn. –

0

Dưới đây là các phương pháp tôi sử dụng để xóa văn bản từ một loại loại kiểm soát triển khai ITextBox.

Tôi nhận thấy trong ví dụ giá trị boolean mặc định được đặt. Tôi chắc rằng bạn có thể sửa đổi nó để đặt giá trị mặc định của các thành phần boolean.

Chuyển phương thức Xóa thành loại điều khiển (Hộp văn bản, Nhãn ... vv) và bộ sưu tập kiểm soát, đồng thời xóa tất cả văn bản khỏi các điều khiển triển khai ITextBox.

Something như thế này:

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

Phương pháp rõ ràng là có nghĩa là cho một trang hoặc Masterpage. Loại bộ sưu tập kiểm soát có thể khác nhau. I E. Biểu mẫu, ContentPlaceHolder .. v.v.

 /// <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; 
     } 
    } 
2

Các giải pháp trên dường như bỏ qua các điều khiển lồng nhau.

Một hàm đệ quy có thể được yêu cầu như:

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

Bạn không muốn chỉ xóa các thuộc tính Text mà không kiểm tra kiểu điều khiển.

Thực hiện một giao diện, như IClearable (theo đề xuất của Bill K), trên một bộ điều khiển dẫn xuất sẽ cắt giảm độ dài của hàm này, nhưng yêu cầu nhiều công việc hơn trên mỗi điều khiển.

+0

Giải pháp mà tôi trình bày sẽ bao gồm các điều khiển lồng nhau. –

+0

Nathan, đó là một giải pháp thú vị. Các khía cạnh lồng nhau của mã không phải là ngay lập tức hiển nhiên từ nhìn vào mã, vì vậy tôi đã không phát hiện ra điều đó. – benPearce

+0

Có một chút nhưng ẩn nhưng hey nó hoạt động tốt –

2

Đây là điều tương tự mà tôi đề xuất trong câu trả lời đầu tiên của tôi nhưng trong VB, cho đến khi chúng tôi nhận VB10 này là tốt nhất chúng tôi có thể làm trong VB vì nó không hỗ trợ chức năng không trở về trong lambdas:

VB giải pháp:

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 

Calling:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
     Me.Controls.ClearControls() 
    End Sub 

tôi chỉ đăng bài này ở đây để mọi người có thể xem cách làm điều tương tự trong VB.

1

khoảng trống riêng tư FormReset() { ViewState.Clear(); Response.Redirect (Request.Url.AbsoluteUri.ToString()); }

3

Tôi biết câu hỏi cũ nhưng chỉ là 2 xu của tôi. Đây là lớp trợ giúp tôi sử dụng để xóa biểu mẫu.

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

Và tôi gọi phương thức từ bất kỳ hình thức nào như thế này chuyển đối tượng biểu mẫu dưới dạng tham số.

Helper.ClearFormControls(this); 

Bạn có thể mở rộng nó cho các loại điều khiển khác. Bạn chỉ cần bỏ nó.

Các vấn đề liên quan