循环遍历窗体上的每个控件(包括容器中的控件),并将文本占位符替换为设置值



在我的项目中,我有一个名为 DriveLetter 的设置,我希望将此设置的值插入到窗体上多个控件的文本中(替换占位符)。

我认为最简单的方法是遍历窗体上的每个控件并搜索占位符,但是通过反复试验,我发现我无法做到这一点(至少以我尝试的方式),因为我使用了容器,例如SplitContainerPanel

以下是我到目前为止所拥有的,它考虑了上述SplitContainerPanel包含,但是我如何修改它以循环遍历窗体上的每个控件,而不必显式检查当前控件是否是一种容器?

Private DRIVE_LETTER As String = My.Settings.DriveLetter
'**
' Handle form loading
''
Private Sub form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
    ReplaceDriveLetter(Me)
End Sub
'**
' Update the value of the <DRIVE_LETTER> text placehoder
''
Private Sub ReplaceDriveLetter(ByVal ctrlContainer As Control)
    For Each ctrl As Control In ctrlContainer.Controls
        If TypeOf ctrl Is SplitContainer Or TypeOf ctrl Is Panel Then
            ReplaceDriveLetter(ctrl)
        Else
            ctrl.Text = Replace(ctrl.Text, "<DRIVE_LETTER>", UCase(DRIVE_LETTER))
        End If
    Next ctrl
End Sub

还可以使用 Control.HasChildren 属性来检查控件是否包含一个或多个子控件。

如 MSDN 所述,如果Controls集合的Count大于零,则 HasChildren 属性将返回 true。如果控件没有子项,则访问 HasChildren 属性不会强制创建Control.ControlCollection,因此在遍历控件树时,引用此属性可以提供性能优势。

因此,您可以在以下位置更改函数:

Private Sub ReplaceDriveLetter(ByVal ctrlContainer As Control)
    For Each ctrl As Control In ctrlContainer.Controls
        If ctrl.HasChildren Then
            ReplaceDriveLetter(ctrl)
        Else
            ctrl.Text = Replace(ctrl.Text, "<DRIVE_LETTER>", UCase(DRIVE_LETTER))
        End If
    Next ctrl
End Sub

这应该可以做到,尽管显然用 DriveLetter 替换了这里的文本(如果您愿意,我可以提供帮助)。

Private Sub ReplaceAllControlsOnForm()
    Dim stackOfControls As New Stack(Of Control)
    'add initial controls (all on form)
    For Each c As Control In Me.Controls
        stackOfControls.Push(c)
    Next
    'go until no controls are left
    While (stackOfControls.Count > 0)
        Dim currControl As Control = stackOfControls.Pop
        currControl.Text = "text here"
        'see if our control can contain controls
        If (currControl.Controls IsNot Nothing AndAlso currControl.Controls.Count > 0) Then
            'add all of these controls onto our stack
            For Each c As Control In currControl.Controls
                stackOfControls.Push(c)
            Next
        End If
    End While
End Sub

最新更新