代码之家  ›  专栏  ›  技术社区  ›  Simos Sigma

按类别属性将属性名称列出到变量中

  •  1
  • Simos Sigma  · 技术社区  · 7 年前

    我正在努力 列表 一些 属性 姓名 类别 属性并将它们放入 变量 .
    例如,获取“属于”类别的所有属性名称 外观 把它们放入变量中。

    我有一个类似的例子,可以重置特定的属性,但是我必须逐个添加它们,这是我想要避免的。

    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 回复  |  直到 7 年前
        1
  •  0
  •   Jimi    7 年前

    您的问题中有四种可能的情况(我可以想到):

    1. (更有可能)获取属性列表 Category DisplayName 而且,如果 PropertyDescriptor.CanResetValue() 方法返回一个正结果,重置属性。
      最终,过滤 类别 插入 .Where 条款。

    2. 获取属于某些预定义类别的属性列表,并重置值与 DefaultValueAttribute PropertyDescriptor.CanResetValue() 方法结果。

    3. 与上面相同,但也添加了要重置的特定属性列表。

    4. 获取属于某些预定义类别的属性列表,并重置所有属性(无论是什么) 属性描述符.canResetValue() 想想看。

    第一种情况:
    使用LINQ查询 TypeDescriptor 创建一个列表 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()
    

    同样,属性列表分组依据 类别 使用 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 与预定义类别列表相关的元素。
    检查 属性描述符.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查询 类型描述符 创建一个列表 属性描述器 与预定义类别列表相关的元素。
    检查 DefaultValueAttribute 财产的 Nothing ,因为 如果是的话, 属性描述符.canResetValue() 将跳过它并寻找一个自定义的方法替换来获得结果。因为这里没有定义任何这样的方法,所以它总是返回false,除非它可以检测到属性已经更改。
    如果没有 默认值属性 存在,或 属性描述符.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