遍历表单上的每个控件(包括容器中的控件)并将文本占位符替换为设置值
Loop through every control on a Form (including those in Containers) and replace a text placeholder with a setting value
在我的项目中,我有一个名为 DriveLetter 的设置,我希望将此设置的值插入到窗体上几个控件的文本中(替换占位符)。
我认为最简单的方法是遍历表单上的每个控件并搜索占位符,但通过反复试验我发现我不能这样做(至少在方式上我正在尝试)因为我使用容器,例如 SplitContainer
和 Panel
.
下面是我到目前为止的内容,其中考虑了前面提到的 SplitContainer
和 Panel
containesr,但是我如何修改它以循环遍历表单上的每个控件而不必显式检查当前控件是否为容器类型?
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
这应该可以做到,尽管显然要用 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
您还可以使用 Control.HasChildren Property 检查控件是否包含一个或多个子控件。
如 MSDN 所述,如果 Controls
集合的 Count
大于零,则 HasChildren
属性 将 return 为真。如果控件没有子控件,则访问 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 的设置,我希望将此设置的值插入到窗体上几个控件的文本中(替换占位符)。
我认为最简单的方法是遍历表单上的每个控件并搜索占位符,但通过反复试验我发现我不能这样做(至少在方式上我正在尝试)因为我使用容器,例如 SplitContainer
和 Panel
.
下面是我到目前为止的内容,其中考虑了前面提到的 SplitContainer
和 Panel
containesr,但是我如何修改它以循环遍历表单上的每个控件而不必显式检查当前控件是否为容器类型?
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
这应该可以做到,尽管显然要用 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
您还可以使用 Control.HasChildren Property 检查控件是否包含一个或多个子控件。
如 MSDN 所述,如果 Controls
集合的 Count
大于零,则 HasChildren
属性 将 return 为真。如果控件没有子控件,则访问 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