本文介绍了在Windows窗体中列出(顶级)声明的变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

创建窗体的实例后,我可以轻松列出窗体中的所有控件.

有没有列出所有 声明的变量 或此类对象的机制?
也许我将其称为声明.仅顶级声明就足够了.

假设我们有带有以下顶级声明的 MyForm 表单:

  Dim Town as String昏暗的ZIP作为字符串昏暗的StreetName作为字符串Dim StreetNo as String公开dtCountries作为DataTable以列表形式(列表)的公共LstCities... 

伪代码示例:

  Dim MyForm as New MyForm'创建表单实例Dim dtVariables as New Datatable'创建一个数据表来存储找到的对象dtVariables.Columns.Add("ID",GetTy(Int32))dtVariables.Columns.Add("VariableName",GetTy(String))dtVariables.Columns.Add("VariableType",GetTy(String))对于MyForm中的每个Varbl.***变量***'<<<(如何)读取所有变量Dim nr as Datarow = dtVariables.NewRownr("ID")= dtVariables.Rows.Count + 1nr("VariableName")= Varbl.Namenr("VariableType")= Varbl.GetType.ToString.Replace("System.Windows.Forms.",")dtVariables.Rows.Add(nr)'将找到的对象/变量添加到我们的数据表中下一个 

我正在寻找的结果是这样的:

  1个城镇字符串2 ZIP字串3 StreetName字符串4街号Int325 dtCountries数据表6个LstCities列表(字符串)…… 

我知道我可以阅读 MyForm.designer.vb 文件并在其中查找声明.
这个问题是关于从Form的对象模型/Form的实例中获取它的.

解决方案

使用

  Dim ClassFields作为新的DataTableClassFields.Columns.Add("ID",GetType(Integer))ClassFields.Columns.Add("Name",GetType(String))ClassFields.Columns.Add("FieldType",GetType(String))Dim标志为BindingFlags = BindingFlags.Instance或BindingFlags.Public或BindingFlags.NonPublic或BindingFlags.DeclaredOnly将allFields设置为List(Of FieldInfo)=Me.GetType().GetFields(flags).Where(Function(f)(不是(f.FieldType.Namespace.Equals("System.Windows.Forms")))AndAlso f.Name<""components").ToList()对于每个字段,作为allFields中的FieldInfoDim dr As DataRow = ClassFields.NewRowdr("ID")= ClassFields.Rows.Count + 1dr("Name")= field.Namedr("FieldType")= GetFieldTypeName(field.FieldType.Name)&GetTypeArguments(field.FieldType.GenericTypeArguments)ClassFields.Rows.Add(dr)下一个私有函数GetFieldTypeName(字段作为字符串)作为字符串昏暗EndPosition为整数= field.IndexOf(ChrW(96))返回If(EndPosition> 0,field.Substring(0,EndPosition),field)结束功能私有函数GetTypeArguments(args作为Type())作为字符串如果args.Length = 0,则返回String.Empty返回$({String.Join(",,args.Select(Function(arg)arg.Name))))"结束功能 

如果插值字符串不可用(在VB.Net版本14之前),请使用复合格式字符串:

 返回$({String.Join(",,args.Select(Function(arg)arg.Name))})" 

可以表示为:

 返回String.Format(({0})",String.Join(,",args.Select(Function(arg)arg.Name))) 

I can easily list all controls in a Form, after creating an instance of it.

Is there any mechanism to list all declared variables or such objects?
Perhaps I shall call it declarations. Only top-level declarations are enough.

Let's assume we have MyForm Form with such top-level declarations:

Dim Town as String
Dim ZIP as String
Dim StreetName as String
Dim StreetNo as String
Public dtCountries as DataTable
Public LstCities as List(Of String)
...

Pseudo-code example:

Dim MyForm as New MyForm          ' create instance of the form
Dim dtVariables as New Datatable  ' create a datatable to store found objects
dtVariables.Columns.Add("ID", GetTy(Int32))
dtVariables.Columns.Add("VariableName", GetTy(String))
dtVariables.Columns.Add("VariableType", GetTy(String))

For Each Varbl In MyForm.***variables***   ' <<< (how) to read all variables
    Dim nr as Datarow = dtVariables.NewRow
    nr("ID") = dtVariables.Rows.Count + 1
    nr("VariableName") = Varbl.Name
    nr("VariableType") = Varbl.GetType.ToString.Replace("System.Windows.Forms.", "")
    dtVariables.Rows.Add(nr)       ' add found object/variable to our datatable
Next

The result I am looking for is something like:

 1   Town         String
 2   ZIP          String
 3   StreetName   String
 4   StreetNo     Int32
 5   dtCountries  DataTable
 6   LstCities    List(Of String)
 ... ...          ...

I know that I can read MyForm.designer.vb file and look there for declarations.
This question is about getting it from an object model of a Form / instance of a Form.

解决方案

An example using a filtered collection of FieldInfo objects returned by Type.GetType().GetFields()

Since you want this method to return both Public and non-Public Fields, the collection must be filtered because, since this is a Form class, it will include all the controls a Form contains.
The collection of FieldInfo is then filtered using FieldType.Namespace, where the Namespace is not System.Windows.Forms.

The BindingFlags are set to Instance | Public | NonPublic | DeclaredOnly.

When the Field represents a Collection (List, Dictionary etc.), the Type.GenericTypeArguments property needs to be parsed to extract the arguments Collection.

I'm using a couple of helper functions to clean up the Fields Name and to retrieve the collection of arguments as a formatted string.

Using the sample Fields you posted (I added a Dictionary to test the output):

Dim Town As String
Dim ZIP As String
Dim StreetName As String
Dim StreetNo As String
Public dtCountries As DataTable
Public LstCities As List(Of String)
Public DictOfControls As Dictionary(Of String, Control)

this is the result:

Dim ClassFields As New DataTable
ClassFields.Columns.Add("ID", GetType(Integer))
ClassFields.Columns.Add("Name", GetType(String))
ClassFields.Columns.Add("FieldType", GetType(String))

Dim flags As BindingFlags = BindingFlags.Instance Or
             BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.DeclaredOnly

Dim allFields As List(Of FieldInfo) =
    Me.GetType().GetFields(flags).
        Where(Function(f) (Not (f.FieldType.Namespace.Equals("System.Windows.Forms"))) AndAlso f.Name <> "components").
        ToList()

For Each field As FieldInfo In allFields
    Dim dr As DataRow = ClassFields.NewRow
    dr("ID") = ClassFields.Rows.Count + 1
    dr("Name") = field.Name
    dr("FieldType") = GetFieldTypeName(field.FieldType.Name) &
                      GetTypeArguments(field.FieldType.GenericTypeArguments)
    ClassFields.Rows.Add(dr)
Next

Private Function GetFieldTypeName(field As String) As String
    Dim EndPosition As Integer = field.IndexOf(ChrW(96))
    Return If(EndPosition > 0, field.Substring(0, EndPosition), field)
End Function

Private Function GetTypeArguments(args As Type()) As String
    If args.Length = 0 Then Return String.Empty
    Return $" ({String.Join(", ", args.Select(Function(arg) arg.Name))})"
End Function

If Interpolated String is not available (before VB.Net version 14), use a Composite Format string:

Return $" ({String.Join(", ", args.Select(Function(arg) arg.Name))})"

can be expressed as:

Return String.Format(" ({0})", String.Join(", ", args.Select(Function(arg) arg.Name)))

这篇关于在Windows窗体中列出(顶级)声明的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 13:59