以编程方式访问位于多个标签页上的 GroupBox 上的控件 [英] Programmatically access controls on GroupBoxes that are on multiple Tab Pages
问题描述
如何以编程方式访问标签页上的控件?
How can you programmatically access controls on Tab Pages?
我的代码有许多属性,我希望允许用户在程序启动时进行初始设置.这些属性将用于定义 Excel 图表,如标题名称、字体颜色、字体大小、图表位置和大小、X &Y 系列和许多其他属性.该程序生成许多图表,每个图表都有自己的一组属性.每个图表都具有相同的属性集,但值不同.
My code has many properties that I want to allow the user to initially set when the program starts. These properties will be used to define an Excel chart like title name, font colors, font size, chart position and size, X & Y series and many others properties. The program produces many charts each of which have their own set of properties. Each chart has the same set of properties but different values.
我使用 Form1 Designer 的解决方案:
My solution using Form1 Designer:
- 我将来自 VS 2010 工具箱的 TabControl1 控件放置在 Form1 上.
- 我在 TabControl1 上创建了 19 个 TabPage
- 在每个 TabPage 上,我为组织创建了多个 GroupBox.
- 最后,我在每个 GroupBox 中放置了多个控件,例如 RadioButton、TextBox 和 Spinner.
- 以上所有内容都是在设计时完成的.
不好的例子:
将 TC1 调暗为 TabControl = TabControl1.TabPages.Item(1)
这是一个不好的例子,但我想我需要做这样的事情,即在我可以通过 RadioButtons、TextBoxes 或 Spinners 子控件访问实际用户输入之前,我需要告诉编译器的名称TabControl1 和其中包含的每个 TabPage.我不确定每个包含 RadioButtons 等的 GroupBoxes.
This is a bad example but I’m thinking I need to do something like this, i.e. before I can reach the actual user inputs via the RadioButtons, TextBoxes, or Spinners child controls I need to tell the complier the name of the TabControl1 and each TabPage contained in it. I’m not sure about each of the GroupBoxes that contain groups of RadioButtons and etc.
我的问题:您如何以编程方式访问位于每个标签页上的多个 GropBox 上的控件?我想在每个 TabPage 上检索所有用户输入属性值,并在创建 Excel 图表时应用它们.
My Question: How do you programmatically access controls located on multiple GropBoxes located on each of the Tab Pages? I want to retrieve all the user input properties values on each of many TabPages and apply them when I create the Excel Charts.
推荐答案
TabControl
只是在同一表单上组织控件的一种奇特方式.关键是它们的形式相同!您可能知道使用 Me
访问当前表单,然后使用 .ControlName
访问控件.考虑一个带有两个选项卡的 TabControl
,每个选项卡上都有一个 TextBox
.这些 TextBox
是在同一个表单上,所以你仍然需要使用
A TabControl
is just a fancy way to organize controls on the same form. The point is that they are on the same form! You probably know that you use Me
to access the current form, then .ControlName
to access the control. Consider a TabControl
with two tabs and on each tab there is a TextBox
. These TextBox
es are on the same form, so you still need to use
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,你可以有 tc1CheckBox1
和 tc1CheckBox2
等.我访问它们的方式是使用 LINQ
This you already knew, as your problem stemmed from this behavior. However, there are some tricks to help you. Consider a TabControl
with two tabs, and on page 1 there is a control named tc1TextBox1
and on page 2 tc2TextBox1
. I'm using the prefix to distinguish between the pages. An additional TextBox
on page 1 would be named tc1TextBox2
etc., then say you wanted CheckBox
es, you could have tc1CheckBox1
and tc1CheckBox2
etc. The way I would access them is with 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
这个方法返回所有parent
中的Control
s,以及它们中的所有Control
s,以此类推,递归.它还为您提供了一个 IEnumerable
List(Of Control)
,而 Control.Controls()
不是 IEnumerable
> 并且只返回控件中的控件,而不是其容器中的控件.
This method returns you all the Control
s inside parent
, and all Control
s inside those, and so on, recursively. It also gives you an IEnumerable
List(Of Control)
in contrast to Control.Controls()
which is not IEnumerable
and only returns controls in the control, not in its containers.
使用LINQ,您可以通过Type
或Name
过滤ChildControls
的结果.例如,代码
Using LINQ, you can filter the results of ChildControls
by Type
or Name
. For instance, the code
Dim textBoxes = Me.ChildControls(Of TextBox)()
返回 Me 中的所有 TextBox
es.让我们更进一步:
returns all the TextBox
es in Me. Let's take it a step further:
Dim textBoxes = Me.ChildControls(Of TextBox)().Where(Function(tb) tb.Name.StartsWith("tc1"))
返回所有带有前缀tc1"的TextBox
es.因此,您可以看到您可以在表单上设置控件,以便在运行时更好地对它们进行分组.这是一个专门针对 Excel 工作表的想法
returns all the TextBox
es with the prefix "tc1". So you see you can set up the controls on your form to better group them at runtime. Here's an idea specific for Excel sheets
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
它将遍历您的选项卡控件索引,并为每个相应的 Excel 工作表设置属性.这段代码应该能让您很好地了解可以采取的方向.
which will loop over your tab control indices, and set properties for each corresponding excel sheet. This code should give you a good idea of a direction you can take.
这篇关于以编程方式访问位于多个标签页上的 GroupBox 上的控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!