以编程方式访问位于多个标签页上的 GroupBox 上的控件 [英] Programmatically access controls on GroupBoxes that are on multiple Tab Pages

查看:31
本文介绍了以编程方式访问位于多个标签页上的 GroupBox 上的控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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:

  1. 我将来自 VS 2010 工具箱的 TabControl1 控件放置在 Form1 上.
  2. 我在 TabControl1 上创建了 19 个 TabPage
  3. 在每个 TabPage 上,我为组织创建了多个 GroupBox.
  4. 最后,我在每个 GroupBox 中放置了多个控件,例如 RadioButton、TextBox 和 Spinner.
  5. 以上所有内容都是在设计时完成的.

不好的例子:

将 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 TextBoxes 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 等,然后说你想要 CheckBoxes,你可以有 tc1CheckBox1tc1CheckBox2 等.我访问它们的方式是使用 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 CheckBoxes, 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中的Controls,以及它们中的所有Controls,以此类推,递归.它还为您提供了一个 IEnumerable List(Of Control),而 Control.Controls() 不是 IEnumerable> 并且只返回控件中的控件,而不是其容器中的控件.

This method returns you all the Controls inside parent, and all Controls 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,您可以通过TypeName 过滤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 TextBoxes in Me. Let's take it a step further:

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

返回所有带有前缀tc1"的TextBoxes.因此,您可以看到您可以在表单上设置控件,以便在运行时更好地对它们进行分组.这是一个专门针对 Excel 工作表的想法

returns all the TextBoxes 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆