Перечислите имена свойств в переменную по атрибуту категории - PullRequest
0 голосов
/ 27 мая 2018

Я пытаюсь перечислить некоторые свойства имена по атрибуту Category и поместить их в переменную .
Например, чтобы получить все имена свойств, которые «принадлежат» категории Внешний вид и поместить их в переменную.

У меня есть похожий пример, который сбрасывает определенные свойства, но я должен добавитьих один за другим, которых я хочу избежать.

Dim _Form As Form = CType(Me, Form)
Dim ListOfPropertyNames As New List(Of String) From {"BackColor", "ForeColor"}
For Each _Property In ListOfPropertyNames
    Dim _PropertyDescriptor As PropertyDescriptor = TypeDescriptor.GetProperties(_Form)(_Property)
    If _PropertyDescriptor.CanResetValue(_Form) Then
        If _PropertyDescriptor.GetValue(_Form) IsNot Nothing Then
            _PropertyDescriptor.ResetValue(_Form)
        End If
    End If
Next

1 Ответ

0 голосов
/ 28 мая 2018

В вашем вопросе есть четыре возможных сценария (о которых я могу подумать):

  1. (более вероятно) Получить список свойств, упорядоченный по Category и DisplayName и, если метод PropertyDescriptor.CanResetValue () возвращает положительный результат, сбросьте свойство.
    В конце концов, отфильтруйте Category, вставив предложение .Where.

  2. Получите список свойств, которые принадлежат некоторым предварительно определенным категориям, и сбросьте все свойства, значения которых отличаются от DefaultValueAttribute , проверив результат метода PropertyDescriptor.CanResetValue().

  3. То же, что и выше, но также добавление списка конкретных свойств для сброса.

  4. Получить список свойствкоторые принадлежат к некоторым заранее определенным категориям и сбрасывают все свойства независимо от того, что об этом думает PropertyDescriptor.CanResetValue().

Первый сценарий:
Используя LINQ, запросите TypeDescriptor для создания списка ProЭлементы pertyDescriptor , упорядоченные по Category и DisplayName.
Проверка результата PropertyDescriptor.CanResetValue() и сброс значения свойства по умолчанию, если оно изменилось.

Dim PropertyCollection As List(Of PropertyDescriptor) = TypeDescriptor.
                                                        GetProperties(_Form).
                                                        OfType(Of PropertyDescriptor).
                                                        OrderBy(Function(item) item.Category).
                                                        ThenBy(Function(item) item.DisplayName).
                                                        ToList()

For Each _PropertyDescriptor As PropertyDescriptor In PropertyCollection
    If _PropertyDescriptor.CanResetValue(_Form) Then
        If _PropertyDescriptor.GetValue(_Form) IsNot Nothing Then
            _PropertyDescriptor.ResetValue(_Form)
        End If
    End If
Next

То же самоес фильтром категории:

Dim PropertyCollection As List(Of PropertyDescriptor) = TypeDescriptor.
                                                        GetProperties(_Form).
                                                        OfType(Of PropertyDescriptor).
                                                        OrderBy(Function(item) item.Category).
                                                        ThenBy(Function(item) item.DisplayName).
                                                        Where(Function(item) item.Category = "Appearance").
                                                        ToList()

То же самое, группировка списка свойств по Category с использованием GroupBy():

Dim _Form As Form = Me

Dim PropertyCollection As List(Of IGrouping(Of String, PropertyDescriptor)) = TypeDescriptor.
                                  GetProperties(_Form).
                                  OfType(Of PropertyDescriptor).
                                  OrderBy(Function(item) item.Category).
                                  ThenBy(Function(item) item.DisplayName).
                                  GroupBy(Function(item) item.Category).
                                  ToList()

'Extract one Category. It could also be a second For Each loop.
Dim CategoryPropertyList As List(Of PropertyDescriptor) = PropertyCollection.
                                                          SelectMany(Function(grp) grp).
                                                          Where(Function(prop) prop.Category = "Appearance").
                                                          ToList()

For Each _PropertyDescriptor As PropertyDescriptor In CategoryPropertyList

    If _PropertyDescriptor.CanResetValue(_Form) Then
        If _PropertyDescriptor.GetValue(_Form) IsNot Nothing Then
            _PropertyDescriptor.ResetValue(_Form)
        End If
    End If
Next

Второй сценарий:
Используя LINQ, запросите TypeDescriptor, чтобы создать список из PropertyDescriptor элементов, связанных с предопределенным списком категорий.
Проверьте PropertyDescriptor.CanResetValue() результат и сбросьте значение свойства по умолчанию, если оно изменилось.

Dim _Form As Form = CType(Me, Form)
Dim ListOfCategoryNames As New List(Of String) From {"Appearance", "Behavior"}

For Each Category As String In ListOfCategoryNames
    Dim _PropertyCollection As List(Of PropertyDescriptor) = TypeDescriptor.
                                                             GetProperties(_Form).
                                                             OfType(Of PropertyDescriptor).
                                                             Where(Function(item) item.Category = Category).
                                                             ToList()

    For Each _PropertyDescriptor As PropertyDescriptor In _PropertyCollection
        If _PropertyDescriptor.CanResetValue(_Form) Then
            If _PropertyDescriptor.GetValue(_Form) IsNot Nothing Then
                _PropertyDescriptor.ResetValue(_Form)
            End If
        End If
    Next
Next

Сценарий третьего случая:
То же, что и выше, но добавьте фильтр для некоторых конкретных свойств:

Dim ListOfCategoryNames As New List(Of String) From {"Appearance", "Behavior"}
Dim ListOfPropertyNames As New List(Of String) From {"BackColor", "ForeColor", "AllowDrop", "Enabled"}

For Each Category As String In ListOfCategoryNames
    For Each PropertyName As String In ListOfPropertyNames
        Dim _PropertyDescriptor As PropertyDescriptor = TypeDescriptor.GetProperties(_Form).
                                                        OfType(Of PropertyDescriptor).
                                                        Where(Function(item) item.Category = Category AndAlso
                                                                             item.Name = PropertyName).
                                                        FirstOrDefault()

        If (_PropertyDescriptor IsNot Nothing) AndAlso _PropertyDescriptor.CanResetValue(_Form) Then
            If _PropertyDescriptor.GetValue(_Form) IsNot Nothing Then
                _PropertyDescriptor.ResetValue(_Form)
            End If
        End If
    Next
Next

Сценарий четвертого случая:
Использование LINQзапросите TypeDescriptor, чтобы создать список PropertyDescriptor элементов, связанных с предварительно определенным списком категорий.
Проверьте, является ли DefaultValueAttribute свойства равным Nothing, потому что, если это так, PropertyDescriptor.CanResetValue() пропустит егои искать альтернативу пользовательского метода, чтобы получить результат.Поскольку здесь не определены такие методы, он всегда будет возвращать false, если не сможет обнаружить, что свойство было изменено.
Если нет DefaultValueAttribute или PropertyDescriptor.CanResetValue() возвращает True, все значения свойств сбрасываются на значение по умолчанию, предварительно проверив, что для свойства существует метод ResetValue () .

Dim _Form As Form = CType(Me, Form)
Dim ListOfCategoryNames As New List(Of String) From {"Appearance", "Behavior"}

For Each Category As String In ListOfCategoryNames
    Dim _PropertyCollection As List(Of PropertyDescriptor) = TypeDescriptor.
                                                             GetProperties(_Form).
                                                             OfType(Of PropertyDescriptor).
                                                             Where(Function(item) item.Category = Category).
                                                             ToList()

    For Each _PropertyDescriptor As PropertyDescriptor In _PropertyCollection
        Dim _DefaultAttribute As DefaultValueAttribute = _PropertyDescriptor.
                                                         Attributes.OfType(Of DefaultValueAttribute).
                                                         Where(Function(item) item.IsDefaultAttribute).
                                                         FirstOrDefault

        If (_DefaultAttribute Is Nothing) Or (_PropertyDescriptor.CanResetValue(_Form)) Then
            If _PropertyDescriptor.GetType().GetMethod("ResetValue", BindingFlags.Public Or BindingFlags.Instance) IsNot Nothing Then
                If _PropertyDescriptor.GetValue(_Form) IsNot Nothing Then
                    _PropertyDescriptor.ResetValue(_Form)
                End If
            End If
        End If
    Next
Next
...