问题描述
创建窗体的实例后,我可以轻松列出窗体中的所有控件.
有没有列出所有 声明的变量 或此类对象的机制?
也许我将其称为声明.仅顶级声明就足够了.
假设我们有带有以下顶级声明的 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窗体中列出(顶级)声明的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!