【问题标题】:Is there a way to iterate through all the controls in my project?有没有办法遍历我项目中的所有控件?
【发布时间】:2022-01-09 18:38:07
【问题描述】:

我想知道是否有一种方法可以遍历我项目中的所有控件。将它们放在 WinForm 或 UserControl 上,即使它们没有被加载。我想这样做,以便我可以获取每个控件的 .Tag 属性,以及它的名称和父级。

到目前为止,我可以获取 My 命名空间中的每种类型,但从那里我不知道该怎么做。

Private Function GetTypesInNamespace(ByVal assembly As Assembly, ByVal [nameSpace] As String) As Type()
    Return assembly.GetTypes().Where(Function(t) String.Equals(t.[Namespace], [nameSpace], StringComparison.Ordinal)).ToArray()
End Function

【问题讨论】:

  • 我知道问为什么通常是不好的回应,但是 - 为什么你需要这样的信息?
  • dr.null 的链接几乎是我所需要的。问题是,我想遍历项目中所有容器中的所有控件(表单或用户控件),这样我就可以构建一个树视图与他们。我需要它,所以我可以,然后只为我从树视图中选择的那些添加一个标签。
  • “您在项目中拥有的所有控件”实际上并不清楚。您的函数获得类型,但这些没有实例化,因此您没有获得对象的实际实例,因此您没有获得标签等。这进一步得到证实,因为您从仅列出类型的程序集开始。如果你想要实例,那么这不是在程序集上完成,而是在一个正在运行的应用程序上完成。所以虽然这是一个有趣的想法,但我认为你需要澄清你真正希望做什么,以及为什么。
  • 为了更清楚:我有一个 mysql 表,我想在其中存储有关控件(按钮、文本框、dgv_cells、列表框等)的一些信息。我从你指向link 的帖子中遇到的问题是我得到一个“System.MissingMethodException”,我不能在用户控件上使用它(它又拥有自己的控件)。

标签: vb.net loops types


【解决方案1】:

我将为此忽略命名空间。如果您愿意,可以添加它。但是这个函数做了你的函数声称要做的事情。

Public Function getAllTypesOfControl(assembly As Assembly) As IEnumerable(Of Type)
    Return assembly.GetTypes().
        Where(Function(t) t.IsSubclassOf(GetType(ContainerControl))).
        SelectMany(Function(container) container.GetFields(BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.Public)).
        Where(Function(f) f.FieldType.IsSubclassOf(GetType(Control))).
        Select(Function(f) f.FieldType)
End Function

现在,您留下了在控件中定义的所有控件的所有类型,这些控件是 ContainerControls。正如您所提到的,这应该包括在 Forms 和 UserControls 中定义的控件。

你能用这个做点什么吗?我不这么认为,因为您希望访问控件的实例。要做到这一点,您不应该处理大会制度,而是您的 runtime,它应该具有您的实例化控件。我想?

您可能想查看Application.OpenForms,并迭代所有打开的表单,并返回所有控件。

Public Function getAllInstantiatedControls() As IEnumerable(Of Control)
    Return Application.OpenForms.Cast(Of Form).
        SelectMany(Function(openForm) openForm.Controls.Cast(Of Control)().
            Select(Function(c) c.Controls.Cast(Of Control).Append(c))).
        SelectMany(Function(c) c)
End Function

您可能想要第二个,因为您不能只对类型进行操作,因为我知道您想要存储控件属性。所以让我分解你的问题。 You said

...[表单中的组件] 存储在我的项目中,我可以轻松查看/修改它们的详细信息...

是的,但是您知道这些详细信息是如何存储的吗?实际上,它们不是存储的,而是在构造表单时设置的。实际上,Visual Studio 需要运行 InitializeComponent 以便向您展示设计器 - 每次您对控件进行更改时。所以细节实际上是这样存储的(在设计器代码 Form1.Designer.vb 中),上面有一个名为 Button1 的按钮。

设计

Form1.Designer.vb

Partial Class Form1
    Inherits System.Windows.Forms.Form

    Public Sub New()
        InitializeComponent()
    End Sub

    Private Sub InitializeComponent()
        ' ...
        Me.Button1 = New System.Windows.Forms.Button()
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(157, 103)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(75, 23)
        Me.Button1.TabIndex = 3
        Me.Button1.Text = "Button1"
        Me.Button1.UseVisualStyleBackColor = True
        '
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(203, 114)
        Me.Controls.Add(Me.Button1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)
    End Sub

    Friend WithEvents Button1 As Button
End Class

您可以修改或删除该按钮,然后观察 Form1.Designer.vb 中的代码更改或消失。因此,您的“详细信息”存储在代码中。这就是 Visual Basic 中的“Visual”在幕后的含义。

所以这些细节只有在你运行 InitializeComponent 时才会设置,这意味着它们有两种设置方式:

  1. 在 Visual Studio Form1 设计视图中
  2. 当应用程序运行并创建 Form1 实例时

除了这两种方式之外,控件属性没有你的值,并且只有默认值(但这确实是一种不可能的情况并且相关性值得怀疑)。

了解这一点后,您必须访问控件的实例,这可以通过 Application.OpenForms 选项实现。我认为您可以加载所有控件,并写入一些设置文件或数据库,还可以读取并查找控件并根据设置文件或数据库更新它们。不过我不是这么写的。我想我回答了你的问题。

【讨论】:

  • 非常感谢!我今晚没有时间彻底测试它,但第一个功能看起来像我需要的。老实说,它对我来说也是从另一个星球上看的。我的意思是,我理解它的作用,但我对它的简单性和复杂性感到困惑。是否有此类查询的完整文档?
  • 另外,我没有尝试访问任何实例。这仅用于在 IDE/Designer 中保存有关已设计控件的批量信息。当我需要任何控件的任何属性时,我打算在运行的表单/控件上使用它作为 me.controls([DataTable.Field(NameOfControl)).property = [DataTable](FieldValue) --> 不是代码,很明显 :) 再次感谢,迫不及待地想明天测试一下
  • @AdelinaAndreeatrandafir 您的上一条评论中存在一些矛盾,请查看i'm not trying to access any instancei intend to use it on a running form。看,控件没有属性值,直到控件被实例化。我将发布一些设计器代码来说明这一点。
  • 显然你是对的。我确实获得了类型信息,但我无法转换它,所以我无法获得它的属性。我还有很多东西要学……所以,最后,我的计划似乎行不通。感谢您的所有帮助:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-27
  • 1970-01-01
  • 2010-09-14
  • 2021-11-02
  • 2010-11-20
  • 2019-09-14
  • 1970-01-01
相关资源
最近更新 更多