I am trying to list some properties names by Category attribute and put them into a variable.
For example, to get all properties names which "belong" to category Appearance and put them into a variable.
I have a similar example which resets specific properties, but I have to add them one by one which I want to avoid.
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
There are four possible scenarios in your question (that I can think of):
(More probable) Get the List of Properties ordered by Category
and DisplayName
and, if the PropertyDescriptor.CanResetValue() method returns a positive result, reset the Property.
Eventually, filter by Category
inserting a .Where
clause.
Get the List of Properties which belong to some pre-defined Categories and reset all the Properties that have a value different from the DefaultValueAttribute, checking the PropertyDescriptor.CanResetValue()
method result.
Same as above, but also adding a list of specific Properties to reset.
Get the List of Properties which belong to some pre-defined Categories and reset all the Properties no matter what PropertyDescriptor.CanResetValue()
thinks about it.
First case scenario:
Using LINQ, query the TypeDescriptor to build a list of PropertyDescriptor elements ordered by Category
and DisplayName
.
Check PropertyDescriptor.CanResetValue()
result and reset the Property value to its default if it has changed.
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
The same with a Category filter:
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()
The same, grouping the Properties list by Category
using 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
Second case scenario:
Using LINQ, query the TypeDescriptor
to build a list of PropertyDescriptor
elements related to a predefined Category list.
Check PropertyDescriptor.CanResetValue()
result and reset the Property value to its default if it has changed.
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
Third case scenario:
Same as above, but add a filter for some specific properties:
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
Fourth case scenario:
Using LINQ, query the TypeDescriptor
to build a list of PropertyDescriptor
elements related to a predefined Category list.
Check whether the DefaultValueAttribute
of a Property is Nothing
, because
if it is, PropertyDescriptor.CanResetValue()
will skip it and look for a custom method alternative to get the result. Since no such methods are definined here, it will always return false unless it can detect that a Property has been changed.
If no DefaultValueAttribute
is present, or PropertyDescriptor.CanResetValue()
returns True
, resets all Properties values to Default, checking beforehand that a ResetValue() method exists for the Property.
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