Introduction
Dropdown lists in the PropertyGrid provide an easy way to set up controls at design time. However, in some cases the options presented may not be known ahead of time or may vary based on some other setting. VB.NET does not provide an easy way to change the options available. This article gives a concise example of how to implement a dynamic dropdown property in the PropertyGrid.
Background
The code presented here brings together the following resources and combines them into a simple-to-use VB.Net solution:
- PropertyGrid and DropDown properties
- Using PropertyGrid, Part I
- ShouldSerialize and Reset Methods
Using the code
Dynamic dropdown properties are composed of three distinct items:
- A global list of values
- A type converter
- The property definition
Global values
In order for a list of values to appear in a dropdown list of the PropertyGrid, they must be accessible to our type converter. If we want to be able to change the list of values from within our class, they must also be accessable to the class. The solution to this is to place our list of values in an array located globally within the namespace. Here, we create a global class, GlobalClass, which wraps a string array OptionStringArray that will be used to hold the values displayed in our dropdown list.
Friend Class GlobalClass
Friend Shared OptionStringArray(0) As String
End Class
Type converter
A type converter provides a unified way of converting types of values into other types. The OptionConverter overloads the GetStandardValuesSupported, GetStandardValuesExclusive, and GetStandardValues methods of its inherited StingConverter class. GetStandardValuesSupported returns true, indicating that the type supports standard values and that the PropertyGrid should display these values within a dropdown combo box. GetStandardValuesExclusive returns true to indicate that the standard values are locked and will not support freeform entry. GetStandardValues returns the StandardValuesCollection value created from GlobalClass.OptionStringArray. This collection is what is used to populate the dropdown list.
Public Class OptionConverter
Inherits StringConverter
Public Overloads Overrides Function GetStandardValuesSupported( _
ByVal context As ITypeDescriptorContext) As Boolean
Return True End Function
Public Overloads Overrides Function GetStandardValuesExclusive( _
ByVal context As ITypeDescriptorContext) As Boolean
Return True End Function
Public Overloads Overrides Function GetStandardValues( _
ByVal context As ITypeDescriptorContext) As StandardValuesCollection
Return New StandardValuesCollection(GlobalClass.OptionStringArray)
End Function
End Class
Property definition
The property definition can be divided into three sections:
- The local variable
- The exposed property
- The default values
Local variable
The local variable simply holds the selected option.
Private _SelectedOption As String
Exposed property
OptionConverter is passed to the type converter and presents the GlobqalClass.OtionStringArray to the PropertyGrid as a selection list. If an item has already been selected and is in the local variable _SelectedOption, it is returned by the Get method. If no item is selected, then the first option is returned. When the Set method is employed, the local variable _SelectedOption is set to the value that is passed in.
<Browsable(True), TypeConverter(GetType(OptionConverter))> _
Public Property OptionList() As String
Get
Dim TempString As String = ""
If _SelectedOption Is Nothing Then
If GlobalClass.OptionStringArray.GetUpperBound(0) > 0 Then
Array.Sort(GlobalClass.OptionStringArray)
End If
TempString = GlobalClass.OptionStringArray(0)
Else TempString = _SelectedOption
End If
Return TempString
End Get
Set(ByVal Value As String)
_SelectedOption = Value
End Set
End Property
Default values
Because DefaultValueAttribute requires a constant and our dropdown property list is dynamic, we need to use an alternate method to provide a default value. This will both allow the dynamic default to appear in regular text in the property grid and allow the value to be reset to the default using the right click "reset" option.

Two methods are used to produce this behavior: ShouldSerializeOptionList() and ResetOptionList(). These methods must end in the exact same name as the exposed property or they will not work. If _SelectedOption is equal the the desired default option, then false should be returned by ShouldSerializeOptionList(). Otherwise, ShouldSerializeOptionList() should return true to indicate that a bold font should be used. When ResetOptionList() is called, the SelectedOption should be changed back to the default option.
Public Function ShouldSerializeOptionList() As Boolean
Return Not _SelectedOption = GlobalClass.OptionStringArray(0)
End Function
Public Sub ResetOptionList()
_SelectedOption = GlobalClass.OptionStringArray(0)
End Sub
Points of interest
To change the contents of the dropdown list, redim the GlobalClass.OptionStringArray to the desired size and set each element to the desired value. An example is provided below.
Private _NumberOfDynamicOptions As Integer Public Property NumberOfDynamicOptions() As Integer
Get
Return _NumberOfDynamicOptions
End Get
Set(ByVal Value As Integer)
If Value < 0 Then _NumberOfDynamicOptions = 0 ElseIf Value > 100 Then _NumberOfDynamicOptions = 100 Else _NumberOfDynamicOptions = Value
End If
ReDim GlobalClass.OptionStringArray(_NumberOfDynamicOptions)
Dim LoopCount As Integer For LoopCount = 0 To _NumberOfDynamicOptions
GlobalClass.OptionStringArray(LoopCount) = _
LoopCount.ToString + " " + Chr(33 + LoopCount).ToString
Next
End Set
End Property
History
- 19 July, 2007 -- Original version posted