Reputation: 714
Is there a way to declare a property of type dictionary of string, string in VB.Net. I am using this on a usercontrol to add properties via the designer.
I tried the following:
Private v As Dictionary(Of String, String)
Public Property VList As Dictionary(Of String, String)
Get
Return v
End Get
Set(ByVal value As Dictionary(Of String, String))
v = value
End Set
End Property
But when I try this the string collection editor window opens up but the add & remove buttons are disabled. What is the correct way to declare this property?
I want to add the key & value via the designer.
Upvotes: 1
Views: 3134
Reputation: 38865
The Dictionary
does not have a built in UITypeEditor
. There are many reasons why there isn't: there are 2 Types which are generic, it also doesnt have an Item
accessor, there is no simple Add
method, the key must be unique and there is no built in way to serialize a Dictionary "item".
The right way is to use a Collection class inheriting from Collection<T>
so you can control access to the contents (note: this is from System.Collections.ObjectModel
not the horrible VB Collection!). The fast way to setup a working interface is to use a List(Of myTypeClass)
, but this is dangerous in production code because it allows all sorts of actions on the innerlist which you likely do not want.
<Serializable><TypeConverter(GetType(FooConverter))>
Public Class FooBar
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
Public Property Name As String
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
Public Property Value As String
' simple ctor REQUIRED for the UITypeEditor
Public Sub New()
Name = ""
Value = ""
End Sub
' ctor for the TypeConverter (NOT included)
Public Sub New(n As String, v As String)
Name = n
Value = v
End Sub
Public Overrides Function ToString
Return Name
End Sub
End Class
' must be instanced
Private myFoo As New List(Of FooBar)
' list is an object so it cant be serialized, but the CONTENTS can be
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
Public Property FooList As List(of FooBar)
Get
If myFoo Is Nothing Then
myFoo = New List(of FooBar)
End If
Return myFoo
End Get
Set
' do nothing
End Set
End Sub
' for designer serialization
Private Function ShouldSerializeFooList As Boolean
Return myFoo.Count > 0 ' or myFoo IsNot Nothing
End Sub
public Sub ResetMyFolist
myFoo = New List(of FooBar)
End Sub
Caveats:
It is almost always better to write a class container for the Foobar items. Usually you would inherit from Collection<T>
. List<T>
as shown is a container and a collection, so the contents can be cleared, reset, modified etc when exposed as shown. They are fast and easy to implement though and the basic concept is the same.
If a Dictionary is really what you want, you can write your own UITypeEditor
(not UIDesigner, this is not a control) but this would probably require a great deal of work on many levels. The reason there are not gobs of them flying around is that most people make do with one of the standard collections and simply enforce unique names in other ways. (Adding "Properties" to a usercontrol, suggests that really the key
or name ought to be fixed and known to the app ahead of time so it knows what it is and what to do with it(?)).
Often VS can perform designer serialization on its own with simple properties like those in FooBar
. However, since they are items in a collection, you will likely need to also write a TypeConverter
which can return an InstanceDescriptor
, to help VS instance them. But that is a different question.
Upvotes: 2