2011-01-12 26 views
9

Tôi có một số hộp văn bản trong biểu mẫu thắng, một số trong số đó nằm trong một hộp nhóm. Tôi đã cố gắng lặp lại tất cả các hộp văn bản trong biểu mẫu của tôi:lặp qua tất cả các hộp văn bản trong một biểu mẫu, bao gồm cả các hộp bên trong một hộp nhóm

For Each c As Control In Me.Controls 
    If c.GetType Is GetType(TextBox) Then 
     ' Do something 
    End If 
Next 

Nhưng dường như bỏ qua hộp bên trong và chỉ lặp lại các hộp văn bản khác của biểu mẫu. Vì vậy, tôi đã thêm một Đối Mỗi vòng lặp cho textbox GroupBox:

For Each c As Control In GroupBox1.Controls 
    If c.GetType Is GetType(TextBox) Then 
     ' Do something 
    End If 
Next 

Tôi tự hỏi: có cách nào để lặp qua tất cả các hộp thoại trong một hình thức - kể cả những người bên trong một GroupBox - với một single Đối Mỗi vòng lặp? Hoặc bất kỳ cách nào tốt hơn/thanh lịch hơn để làm điều đó?

Xin cảm ơn trước.

+0

Có thể trùng lặp [Làm cách nào để có được TẤT CẢ các điều khiển con của biểu mẫu Windows Biểu mẫu của một loại cụ thể (Button/Textbox)?] (Https://stackoverflow.com/questions/3419159/how-to-get -nút-con-điều khiển-of-a-windows-form-form-of-a-cụ thể-loại-nút) – PulseJet

Trả lời

17

Bạn có thể sử dụng chức năng này, linq có thể là một cách thanh lịch hơn.

Dim allTxt As New List(Of Control) 
For Each txt As TextBox In FindControlRecursive(allTxt, Me, GetType(TextBox)) 
    '....' 
Next 

Public Shared Function FindControlRecursive(ByVal list As List(Of Control), ByVal parent As Control, ByVal ctrlType As System.Type) As List(Of Control) 
    If parent Is Nothing Then Return list 
    If parent.GetType Is ctrlType Then 
     list.Add(parent) 
    End If 
    For Each child As Control In parent.Controls 
     FindControlRecursive(list, child, ctrlType) 
    Next 
    Return list 
End Function 
1

Bạn muốn làm đệ quy, ví dụ (giả, vì tôi không biết VB):

Sub LoopControls (Control Container) 
    if (Container has Controls) 
     LoopControls(Container) 
    For Each c As Control In Container 
     if (Control is TextBox) 
      // do stuff 
End Sub 

Bạn sẽ vượt qua hình thức của bạn (tôi) để các tiểu ban đầu, và nó sẽ đi qua các điều khiển trong nó tìm kiếm những người có chứa nhiều điều khiển hơn.

Ngoài ra kiểm tra câu hỏi này: VB.NET - Iterating through controls in a container object

0

Bạn sẽ cần phải sử dụng đệ quy. Sau đây là một giải pháp C# sử dụng một phương pháp mở rộng và đi xa hơn một chút so với phạm vi của câu hỏi của bạn nhưng tôi chỉ cần kéo nó từ khuôn khổ của chúng tôi.

static partial class ControlExtensions 
{ 
    public static void ApplyToMatchingChild(this Control parent, Action<Control> actionToApplyWhenFound, bool keepApplyingForever, params Func<Control, bool>[] matchingChildCriteria) 
    { 
     ControlEventHandler reapplyEventHandler = null; 
     if (keepApplyingForever) 
     { 
      reapplyEventHandler = (s, e) => 
      { 
       ApplyToMatchingChild(e.Control, actionToApplyWhenFound, keepApplyingForever, matchingChildCriteria); 
      }; 
     } 
     SearchForMatchingChildTypes(parent, actionToApplyWhenFound, reapplyEventHandler, matchingChildCriteria); 
    } 

    private static void SearchForMatchingChildTypes(Control control, Action<Control> actionToApplyWhenFound, ControlEventHandler reapplyEventHandler, params Func<Control, bool>[] matchingChildCriteria) 
    { 
     if (matchingChildCriteria.Any(criteria => criteria(control))) 
     { 
      actionToApplyWhenFound(control); 
     } 

     if (reapplyEventHandler != null) 
     { 
      control.ControlAdded += reapplyEventHandler; 
     } 

     if (control.HasChildren) 
     { 
      foreach (var ctl in control.Controls.Cast<Control>()) 
      { 
       SearchForMatchingChildTypes(ctl, actionToApplyWhenFound, reapplyEventHandler, matchingChildCriteria); 
      } 
     } 
    } 
} 

Và để gọi:

myControl.ApplyToMatchingChild(c => { /* Do Stuff to c */ return; }, false, c => c is TextBox); 

Điều đó sẽ áp dụng một chức năng để tất cả các textbox đứa trẻ. Bạn có thể sử dụng tham số keepApplyingForever để đảm bảo rằng chức năng của bạn sẽ được áp dụng khi các điều khiển con sau này được thêm vào. Hàm này cũng sẽ cho phép bạn chỉ định bất kỳ số lượng tiêu chí phù hợp nào, ví dụ, nếu điều khiển cũng là nhãn hoặc một số tiêu chí khác.

Chúng tôi thực sự sử dụng điều này như một cách gọn gàng để gọi vùng chứa tiêm phụ thuộc của chúng tôi cho mỗi UserControl được thêm vào Biểu mẫu của chúng tôi.

Tôi chắc chắn bạn cũng không nên gặp phải nhiều vấn đề. converting it to VB.NET cũng vậy ... Ngoài ra, nếu bạn không muốn chức năng "keepApplyingForever", bạn cũng nên dễ dàng tách nó ra.

0

Nếu bạn không quan tâm đến thứ tự (và tôi không thể tưởng tượng lý do tại sao bạn nên) của các điều khiển, bạn có thể làm điều này lặp đi lặp lại trong thời trang sau (nó khá đơn giản, vì vậy tôi không nghĩ bất kỳ lời giải thích nào là cần thiết). Nên hiệu quả hơn nhiều so với bất kỳ đệ quy nào, đặc biệt nếu bạn có nhiều điều khiển lồng nhau, mặc dù tôi nghi ngờ nếu hiệu suất đạt được sẽ rõ ràng.

Public Function FindAllControlsIterative(ByRef parent As Control) As List(Of TextBox) 
    Dim list As New List(Of TextBox) 
    Dim ContainerStack As New Stack(Of Control) 
    ContainerStack.Push(parent) 
    While ContainerStack.Count > 0 
     For Each child As Control In ContainerStack.Pop().Controls 
      If child.HasChildren Then ContainerStack.Push(child) 
      If child.GetType Is GetType(TextBox) Then list.Add(child) 
     Next 
    End While 
    Return list 
End Function 
Các vấn đề liên quan