vb.net - 使用 GetField 调用Member。在 VB.NET 中找不到字段

标签 vb.net reflection

这可能是一个简单的问题,但我似乎无法弄清楚。

我有一堆由表单设计器创建的表单项,声明为(在 frmAquRun.Designer.vb 中)

Public WithEvents btnAquRunEvent1 As VisibiltyButtonLib.VisibilityButton
Public WithEvents btnAquRunEvent2 As VisibiltyButtonLib.VisibilityButton

...等

我基本上希望能够为访问每个字段的函数提供一个数字。所以我写了这个函数。 (在 frmAquRun.vb 中)

Const EVENT_BUTTON_PREFIX As String = "btnAquRunEvent"
Public Function getEventButton(ByVal id As Integer) As Windows.Forms.Button

    Dim returnButton As Windows.Forms.Button = Nothing
    Try
        returnButton = DirectCast(Me.GetType().InvokeMember(eventButtonName, Reflection.BindingFlags.GetField Or Reflection.BindingFlags.Public Or Reflection.BindingFlags.Instance, Nothing, Me, Nothing), Windows.Forms.Button)
    Catch ex As Exception
    End Try
    Return returnButton
End Function

但它似乎总是生成字段未找到异常。 异常中的消息是“未找到字段‘ATSIS_ControlProgram.frmAquRun.btnAquRunEvent1’。”。

消息中的命名空间和表单名称正确。知道我做错了什么吗?

最佳答案

问题在于,对于 WithEvents 字段,VB 实际上创建了一个属性来执行必要的事件处理程序附加和分离。生成的属性具有字段的名称。实际的支持字段被重命名为 _ + 原始名称。1)

因此,为了使您的代码正常工作,只需在按钮名称前添加 _ 前缀或使用与属性 getter 相对应的 BindingFlag(而不是 GetField)。

或者,您可以通过使用表单的 Controls 集合来更轻松地完成此操作:

returnButton = DirectCast(Me.Controls(eventButtonName), Windows.Forms.Button)

但请注意,这仅在按钮位于顶级时才有效,即未嵌套在表单上的容器控件内。

<小时/>

1) 这是 VB 编译器的实现细节,但由于 WithEvents 的处理,它是可移植的(尤其是 Mono 的 vbnc 编译器) VB 语言规范中对字段进行了非常详细的描述。

关于vb.net - 使用 GetField 调用Member。在 VB.NET 中找不到字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2413560/

相关文章:

wpf - Caliburn 的 Screen 不能被 Window 或 UserControl 继承

.net - 如何使用反射判断对象的类型是否为Nullable <T>?

java - 从java类中提取所有字段

Java 反射没有按预期工作

.net - 使用 Get-Member 进行反射

c# - 从日期 vb.net 计算耗时?

jquery - 如何在asp.net(vb.net)中从母版页调用jquery

jquery - 仅当 '/' 是自动完成的最后一个字符时,如何调用 Web 方法?

asp.net - 如何将换行符从多行文本框更改为 HTML <br/> 标记?

java - 如何影响反射中方法的顺序