VB.Net:循环所有表单项,包括 CommonDialogs

Posted

技术标签:

【中文标题】VB.Net:循环所有表单项,包括 CommonDialogs【英文标题】:VB.Net: Looping through all form items, including CommonDialogs 【发布时间】:2010-01-30 13:21:54 【问题描述】:

我正在翻译我的 VB.Net 应用程序,我需要遍历表单上的所有控件。使用递归函数,例如

Public Sub TranslateControl(ByVal Ctrl As Control)
    For Each ChildCtrl As Control In Ctrl.Controls
        ChildCtrl.Text = Translate(ChildCtrl.Text)

        If TypeOf ChildCtrl Is Label Then
            CType(ChildCtrl, Label).Tag = Translate(CType(ChildCtrl, Label).Tag)
        End If

        TranslateControl(ChildCtrl)
    Next
End Sub

效果很好,但它不包括CommonDialog 对象,例如FolderBrowser 对象。如何访问这些对象?我试过这个

    For Each ChildDialog As CommonDialog In Ctrl.Controls
        ChildDialog.Tag = Translate(ChildDialog.Tag)
    Next

但显然存在继承问题,因为CommonDialog 对象不是controls

有没有办法让我遍历表单上显示的所有项目?

非常感谢!

CFP

【问题讨论】:

【参考方案1】:

不,它们是组件,而不是控件。他们的代码实际上存在于 shell 中,它们是由 Microsoft 用非托管 C/C++ 编写的。关于它们的唯一管理是一个小的包装器,它进行必要的 API 调用来显示它们并返回它们的结果。以 OpenFileDialog 为例。

您将遇到的第一个问题是在显示此类对话框时运行您的代码。它是一个对话框,在 ShowDialog() 调用之后,控件不会返回到您的程序,直到用户将其关闭。有相当多的诡计是可能的。检查我在this thread 中的代码以了解该方法。如前所述,该代码适用于任何 shell 对话框以及 MessageBox。

这将为您提供对话框的窗口句柄。接下来,您必须迭代对话框的子窗口。您可以使用 EnumChildWindows API 调用来做到这一点。这为您提供了每个孩子的窗口句柄,然后您可以使用 SendMessage() 对孩子做一些事情。不管是什么,您都没有在问题中指定。

【讨论】:

感谢您的回答!但是,我的问题肯定表述得很糟糕。我的意思是:我已经有办法枚举表单上的控件。但是,此方法仅枚举控件,而不是所有项。我正在寻找一种方法来枚举出现在我的表单上的其他项目,例如FolderBrowserDialog。例如,假设我有一个带有一个标签和一个浏览按钮的表单,它显示一个 FolderBrowserDialog 对象。我希望能够列出表单上的所有项目,包括 FolderBrowser。谢谢! 不开玩笑。您可以通过迭代 Me.components.Components 来迭代表单上的某些组件。但是,这不会产生对话对象,它们不会被添加到集合中。只有反射才能将它们从表单对象中挖掘出来。【参考方案2】:
 Friend Sub resetFormControls(zForm As Form)

尝试使用子程序将所有控件重置为未使用状态:空白文本框、未选中的复选框和单选按钮等。

        For Each zCntl As Control In zForm.Controls
            If zCntl.HasChildren Then
                For Each zChildCntl As Control In zCntl.Controls
                    If zChildCntl.GetType Is GetType(CheckBox) Then
                        CType(zChildCntl, CheckBox).Checked = False
                    End If

                    If zChildCntl.GetType Is GetType(TextBox) Then CType(zChildCntl, TextBox).Text = ""
                    If zChildCntl.GetType Is GetType(TextBox) Then CType(zChildCntl, TextBox).BackColor = Color.White
                    If zChildCntl.GetType Is GetType(RichTextBox) Then CType(zChildCntl, RichTextBox).Text = ""
                    If zChildCntl.GetType Is GetType(RichTextBox) Then CType(zChildCntl, RichTextBox).BackColor = Color.White
                    If zChildCntl.GetType Is GetType(RadioButton) Then CType(zChildCntl, RadioButton).Checked = False

                Next
            End If
            If zCntl.GetType Is GetType(CheckBox) Then CType(zCntl, CheckBox).Checked = False
            If zCntl.GetType Is GetType(TextBox) Then CType(zCntl, TextBox).Text = ""
            If zCntl.GetType Is GetType(TextBox) Then CType(zCntl, TextBox).BackColor = Color.White
            If zCntl.GetType Is GetType(RichTextBox) Then CType(zCntl, RichTextBox).Text = ""
            If zCntl.GetType Is GetType(RichTextBox) Then CType(zCntl, RichTextBox).BackColor = Color.White
            If zCntl.GetType Is GetType(RadioButton) Then CType(zCntl, RadioButton).Checked = False
            If zCntl.GetType Is GetType(DateTimePicker) Then CType(zCntl, DateTimePicker).Text = Now.Date
            If zCntl.GetType Is GetType(ComboBox) Then CType(zCntl, ComboBox).SelectedIndex = 0

        Next
        Application.DoEvents()

    Catch ex As Exception

    End Try
End Sub

【讨论】:

这似乎并没有解决问题,因为 OP 已经使用了 Controls 集合。

以上是关于VB.Net:循环所有表单项,包括 CommonDialogs的主要内容,如果未能解决你的问题,请参考以下文章

vb.net 循环查询结果

导出vs 2005(vb.net)中的所有sql表记录

与关系 vb.net 计数表

除按钮外禁用所有表单项

如何使用 VB.NET 向两个表中插入数据?

使用 vb.net 从 excel 文件更新 SQL 表