Список (верхнего уровня) объявленных переменных в форме Windows - PullRequest
0 голосов
/ 29 декабря 2018

Я могу легко перечислить все элементы управления в форме после создания ее экземпляра.

Существует ли какой-либо механизм для перечисления всех объявленных переменных или таких объектов?
Возможно, я назову это объявлений .Достаточно только объявлений верхнего уровня.

Предположим, у нас есть MyForm Форма с такими объявлениями верхнего уровня:

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)
...

Пример псевдокода:

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

Результат, который я ищуэто что-то вроде:

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

Я знаю, что могу прочитать MyForm.designer.vb файл и посмотреть там объявления.
Этот вопрос касается получения его из объектной модели Form / экземпляра Form.

1 Ответ

0 голосов
/ 29 декабря 2018

Пример использования отфильтрованной коллекции FieldInfo объектов, возвращаемых Type.GetType().GetFields()

Поскольку вы хотите, чтобы этот метод возвращал как открытые, так и непубличные поля,коллекция должна быть отфильтрована, потому что, поскольку это класс Form, он будет включать все элементы управления, которые содержит форма.
Коллекция FieldInfo затем фильтруется с использованием FieldType.Namespace, где Namespace не System.Windows.Forms.

BindingFlags установлены на Instance | Public | NonPublic | DeclaredOnly.

Когда поле представляет коллекцию (список, словарь и т. Д.), Свойство Type.GenericTypeArguments необходимо проанализировать для извлечения аргументов коллекции.

I'mиспользование нескольких вспомогательных функций для очистки имени поля и извлечения набора аргументов в виде отформатированной строки.

Использование примера полей, которые вы разместили (я добавил словарь, чтобы проверить вывод):

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)

это результат:

Class GetType GetFields

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

Если Интерполированная строка недоступна (до версии 14 VB.Net), используйте строку Составной формат :

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

можно выразить как:

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