2010-05-19 37 views
5

Có thể tự động (và khái quát) xóa trạng thái của tất cả các điều khiển con của điều khiển người dùng không? (Ví dụ, tất cả của nó textbox, DropDrownLists, RadioButtons, lưới dữ liệu sủ, lặp, vv - về cơ bản bất cứ điều gì có ViewState)Làm cách nào để tự động xóa tất cả các điều khiển trong điều khiển người dùng?

Tôi đang cố gắng để tránh làm điều gì đó như thế này:

foreach (Control c in myUserControl.Controls) 
{ 
    if (c is TextBox) 
    { 
     TextBox tb = (TextBox)c; 
     tb.Text = ""; 
    } 
    else if (c is DropDownList) 
    { 
     DropDownList ddl = (DropDownList)c; 
     ddl.SelectedIndex = -1; 
    } 
    else if (c is DataGrid) 
    { 
     DataGrid dg = (DataGrid)c; 
     dg.Controls.Clear(); 
    } 

    // etc. 

} 

Tôi tìm kiếm nội dung như sau:

foreach (Control c in myUserControl.Controls) 
    c.Clear(); 

... nhưng rõ ràng là không tồn tại. Có cách nào dễ dàng để thực hiện điều này một cách linh hoạt/chung?

+0

Có thể, tất cả những gì bạn cần là chuyển hướng đơn giản? – Alex

Trả lời

3

Tôi sẽ đề xuất một giải pháp tương tự như Task (ngoại trừ sáu bản sao chỉ ra), chúng ta cần triển khai nó như 1 phương pháp mở rộng và tinh chỉnh chuyển sang loại điều khiển chính xác được truyền vào (tức là sao chép logic của bạn trong câu hỏi của bạn).

public static class ControlExtensions 
{ 
    public static void Clear(this Control c) 
    { 
     if(c == null) { 
      throw new ArgumentNullException("c"); 
     } 
     if (c is TextBox) 
     { 
      TextBox tb = (TextBox)c; 
      tb.Text = ""; 
     } 
     else if (c is DropDownList) 
     { 
      DropDownList ddl = (DropDownList)c; 
      ddl.SelectedIndex = -1; 
     } 
     else if (c is DataGrid) 
     { 
      DataGrid dg = (DataGrid)c; 
      dg.Controls.Clear(); 
     } 
     // etc.... 
    } 
} 

Nó không phải là đặc biệt elegent tìm phương pháp nhưng mã của bạn trong trang/kiểm soát của bạn bây giờ là gọn gàng hơn

foreach (Control c in myUserControl.Controls) { 
    c.Clear(); 
} 

và bạn có thể tất nhiên bây giờ gọi control.Clear() bất cứ nơi nào khác trong bạn mã.

+0

Tôi chấp nhận câu trả lời này bởi vì tôi nghĩ rằng điều này là gần như tôi có thể nhận được ý định ban đầu của tôi. Thật không may, nó có vẻ như là không có cách hoàn toàn năng động của thanh toán bù trừ tất cả các điều khiển con. – Michael

1

Bạn có thể làm

foreach (Control c in myUserControl.Controls) { 
    myUserControl.Controls.Remove(c); 
} 

Vì Controls chỉ là một danh sách, bạn có thể gọi Remove() vào nó, truyền cho nó những gì bạn muốn loại bỏ.

EDIT: Ồ tôi xin lỗi, tôi đã không đọc chính xác. Tôi không biết một cách để làm điều này, có lẽ ai đó ở đây ai là người tốt với Reflection thể làm cho nó nơi bạn có thể làm như

foreach (Control c in myUserControl.Controls) { 
    c = new c.Type.GetConstructor().Invoke(); 
} 

hoặc một cái gì đó, để biến nó thành một thành phần tươi thực hiện.

+1

Tôi nghĩ Michael đang tìm cách xóa các giá trị/trạng thái trong mỗi điều khiển. Không phải bản thân điều khiển từ bộ sưu tập. –

+0

KP: Đúng. Tôi không muốn * xóa * các điều khiển, chỉ xóa chúng (ví dụ: xóa giá trị văn bản TextBox, xóa mục đã chọn trong DropDownList, xóa nội dung của DataGrid/Repeater, v.v.). – Michael

+0

Vâng xin lỗi, đã chỉnh sửa để phản ánh việc đọc kém của tôi. – Nilbert

1

Tôi chưa thử nghiệm, nhưng thanh toán bù trừ chế độ xem cho người dùng có thể hoạt động. Bạn có thể phơi bày một phương pháp tùy chỉnh trên điều khiển người dùng cũng như:

usercontrol:

public void Clear() 
{ 
    this.ViewState.Clear(); 
} 

page:

myUserControlInstance.Clear(); 

Bây giờ một lần nữa tôi đã không kiểm tra. Có thể điều này sẽ chỉ xóa StateBag đối với vùng chứa UserControl, chứ không phải điều khiển lồng nhau/con .. nếu ở trên không hoạt động, bạn có thể thử sử dụng đệ quy để đi xuống cây điều khiển để xóa đường ngắm cho tất cả trẻ em:

usercontrol:

public void Clear() 
{ 
    ClearViewState(this.Controls); 
} 

private void ClearViewState(ControlCollection cc) 
{ 
    foreach(Control c in cc) 
    { 
     if(c.HasControls()) 
     { 
      //clear the child controls first 
      ClearViewState(c.Controls); 
     }   

     //then clear the control itself 
     c.ViewState.Clear(); 
    } 
} 

page:

myUserControlInstance.Clear(); 

Chỉ cần một ý tưởng. Tôi đã không thử nghiệm nó nhưng tôi nghĩ về mặt lý thuyết nó có thể hoạt động. Một ngụ ý sẽ là gọi Clear tại điểm chính xác trong vòng đời trang/điều khiển, nếu không nó có thể không hoạt động.

Hy vọng điều này sẽ hữu ích!

+0

Hmmm .. đã thử nghiệm bản thân này và dường như không hoạt động .. Tôi sẽ chơi với nó lâu hơn một chút khi tôi thích khái niệm .. –

+0

Tôi đã nhảy súng. 'ViewState' không phải là thuộc tính công khai, do đó bạn không thể chỉ xóa nó cho các điều khiển. Tôi thích ý tưởng đệ quy được thảo luận trong câu trả lời khác ... Tôi sẽ để lại câu trả lời này mặc dù nó sẽ không hoạt động trong trường hợp những người khác có cùng suy nghĩ ... –

0

Tại sao không làm như bạn đề nghị:

foreach (Control c in myUserControl.Controls) 
    c.Clear(); 

Và sau đó thực hiện rõ ràng:

public static class UserController 
{ 
    public static void Clear(this Control c) 
    { 
     c.Controls.Clear(); 
    } 

    public static void Clear(this TextBox c) 
    { 
     c.Text = String.Empty; 
    } 
} 

Điều đó sẽ làm điều đó.

+0

-1, Các phương pháp mở rộng không làm điều động . – user7116

+0

Vì vậy, mọi cuộc gọi đến Clear() trong foreach sẽ gọi là Control.Clear tĩnh()? Vì vậy, để làm cho nó hoạt động, bạn sẽ trở lại "if (c là TextBox) ..." bên trong Control.Clear()? Thật vậy, không phải là một giải pháp tốt sau đó. – Task

+0

Chính xác. 'c' được gõ tĩnh như' Control', do đó phương thức mở rộng sẽ tìm kiếm nó cho 'Control'. – user7116

1
myUserControl.Controls.ToList().ForEach(c => myUserControl.Controls.Remove(c)); 

Tuy nhiên, hãy cẩn thận, vì bạn sửa đổi danh sách lặp lại. Điều này có thể dẫn đến một số hành vi kỳ lạ.

+0

Trừ 1 vì xóa điều khiển không liên quan gì đến câu hỏi gốc. –

1

Đặt EnableViewState="false" trên các điều khiển riêng lẻ có thể giúp bạn tiết kiệm công việc, nếu nó không gây ra các sự cố khác cho bạn trong trường hợp này.

1

Còn phương pháp Control.ClearChildViewState thì sao?

MSDN nói

Xóa xem thông tin trạng thái cho tất cả các điều khiển con sự kiểm soát của máy chủ.

Tôi chưa bao giờ sử dụng điều này. Vì vậy, tôi không chắc chắn nếu nó sẽ giúp bạn. Nghe hay, tôi nghĩ :)

+0

Nghe có vẻ như nó phải là giải pháp hoàn hảo, nhưng tiếc là nó không hoạt động. – Michael

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