以编程方式访问多个选项卡页面上的GroupBox上的控件

时间:2014-01-27 15:31:17

标签: vb.net tabs tabcontrol groupbox

如何以编程方式访问标签页上的控件?

我的代码有很多属性,我想让用户在程序启动时初始设置。这些属性将用于定义Excel图表,如标题名称,字体颜色,字体大小,图表位置和大小,X& Y系列和许多其他属性。该程序生成许多图表,每个图表都有自己的属性集。每个图表具有相同的属性集但具有不同的值。

我使用Form1 Designer的解决方案:

  1. 我在Form1上的VS 2010工具箱中放置了TabControl1控件。
  2. 我在TabControl1上创建了19个TabPages
  3. 在每个TabPage上,我创建了多个用于组织的GroupBox。
  4. 最后,我在每个GroupBox中放置了多个控件,如RadioButtons,TextBoxes和Spinners。
  5. 以上所有内容均在设计时完成。
  6. 错误示例:

    Dim TC1 As TabControl = TabControl1.TabPages.Item(1)

    这是一个不好的例子但是我想我需要做这样的事情,即在我通过RadioButtons,TextBoxes或Spinners子控件达到实际用户输入之前我需要告诉编译器的名称TabControl1和其中包含的每个TabPage。我不确定每个包含RadioButtons等组的GroupBox。

    我的问题:如何以编程方式访问位于每个标签页上的多个GropBox上的控件?我想在许多TabPages中检索所有用户输入属性值,并在创建Excel图表时应用它们。

1 个答案:

答案 0 :(得分:3)

TabControl只是在同一表单上组织控件的一种奇特方式。关键是他们是在同一个形式!您可能知道使用Me访问当前表单,然后使用.ControlName来访问控件。考虑带有两个标签的TabControl,每个标签上都有一个TextBox。这些TextBox es在同一表单上,因此您仍需要使用

Me.TextBox1.Text = "Text 1" ' the same as TextBox1.Text = "Text 1", but I like to be explicit
Me.TextBox2.Text = "Text 2"

你已经知道了,因为你的问题源于这种行为。但是,有一些技巧可以帮助你。考虑带有两个标签的TabControl,第1页上有一个名为tc1TextBox1的控件和第2页tc2TextBox1。我正在使用前缀来区分页面。第1页上的其他TextBox会被命名为tc1TextBox2等,然后说您想要CheckBox es,您可以tc1CheckBox1tc1CheckBox2等等。我会使用LINQ

访问它们

在模块中定义扩展方法

Imports System.Runtime.CompilerServices

Public Module ExtensionMethods
    <Extension()> _
    Public Function ChildControls(Of T As Control)(ByVal parent As Control) As List(Of T)
        Dim result As New List(Of Control)
        For Each ctrl As Control In parent.Controls
            If TypeOf ctrl Is T Then result.Add(ctrl)
            result.AddRange(ctrl.ChildControls(Of T)())
        Next
        Return result.ToArray().Select(Of T)(Function(arg1) CType(arg1, T)).ToList()
    End Function
End Module

此方法会返回Controlparent内的所有Control,以及其中的所有IEnumerable,依此类推,递归。它还为List(Of Control) Control.Controls()提供了IEnumerable,而ChildControls不是Type,只返回控件中的控件,而不是其容器中的控件。

使用LINQ,您可以按NameDim textBoxes = Me.ChildControls(Of TextBox)() 过滤TextBox的结果。例如,代码

Dim textBoxes = Me.ChildControls(Of TextBox)().Where(Function(tb) tb.Name.StartsWith("tc1"))

返回Me中的所有TextBox es。让我们更进一步:

Dim xlBook As Excel.Workbook
For i As Integer = 1 To 20
    Dim nameString = "txtSheetName" & i.ToString() ' TextBoxes named txtSheetName1, txtSheetName2, etc.
    xlBook.Sheets(i).Name = Me.ChildControls(Of TextBox)().Where(Function(tb) tb.Name = nameString).First().Text
    Dim enabledString = "chkEnabled" & i.ToString() ' CheckBoxes named chkEnabled1, chkEnabled2, etc.
    xlBook.Sheets(i).Enabled = Me.ChildControls(Of CheckBox)().Where(Function(tb) tb.Name = enabledString).First().Checked
    'etc.
Next

返回前缀为“tc1”的所有{{1}} es。因此,您可以看到可以在表单上设置控件,以便在运行时更好地对其进行分组。这是一个特定于Excel工作表的想法

{{1}}

将循环显示选项卡控件索引,并为每个相应的Excel工作表设置属性。这段代码可以让你很好地了解你可以采取的方向。