PropertyDescriptor for Generic.List(Of String)?

196 views
Skip to first unread message

WALDO

unread,
Jun 1, 2007, 4:59:02 PM6/1/07
to
I have an object which I would like to show on a property grid. The object
has a property that ultimately can boil down to an array of unique strings.
I though I'd be clever and code it as a Generic.List(Of String).

When I select the object so it is shown in a PropertyGrid, it, shows the
default collection editor. So far, so good. When I go to add a value, the
collection editor complains that it can't find a constructor for type
System.String.

That makes sense to me, given that a string doesn't have a parameter-less
constructor.

Does anyone know of a quick-and-dirty way to have an editable property of
strings that will cooperate with the default collection editor in the
fashion I would like? I want to know If I am overthinking it before I create
a custom TypeDescriptor and a custom CollectionEditor.


Any help is appreciated.
Thanks in advance.

WALDO


VisualHint

unread,
Jun 1, 2007, 5:44:35 PM6/1/07
to
Hello Waldo,

if you want to get the true string collection editor, decorate your
property with:
[Editor("System.Windows.Forms.Design.StringCollectionEditor,
System.Design, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a",
typeof(System.Drawing.Design.UITypeEditor))]

Or else, if you want to fix the generic collection editor, implement
something like described on this page:
http://www.dotnet247.com/247reference/msgs/30/153300.aspx
The method CreateInstance of your editor must return an empty string.

Best regards,

Nicolas Cadilhac @ VisualHint (http://www.visualhint.com)
Home of Smart FieldPackEditor.Net / DateTimePicker replacement
Home of Smart PropertyGrid for .Net and MFC
Microsoft PropertyGrid Resource List - http://www.propertygridresourcelist.com


On Jun 1, 4:59 pm, "WALDO" <NOS...@NOSPAM.com> wrote:
> I have an object which I would like to show on a property grid. The object
> has a property that ultimately can boil down to an array of unique strings.
> I though I'd be clever and code it as a Generic.List(Of String).
>

> When I select the object so it is shown in aPropertyGrid, it, shows the

WALDO

unread,
Jun 2, 2007, 10:33:57 AM6/2/07
to
Yeah, I bit the bullet.
 

Imports

System.Drawing.Design
Imports
System.ComponentModel
Imports System.ComponentModel.Design

Public

Class PathCollectionEditor
    Inherits
CollectionEditor

    Public Sub New()
        MyBase.New(GetType(Generic.List(Of String
)))
    End Sub

    Protected Overrides Function CreateCollectionItemType() As System.Type
        Return GetType
(FolderPath)
    End Function

    Protected Overrides Function CanSelectMultipleInstances() As Boolean
        Return
False
    End Function

    Protected Overrides Function GetDisplayText(ByVal value As Object) As String
        Dim displayText As String = String
.Empty
        Dim folder As FolderPath = CType
(value, FolderPath)
        Dim fld As String
= folder.Path

        If (String.IsNullOrEmpty(fld) = False) Then
            Try
                Dim di As New
IO.DirectoryInfo(fld)
                displayText = di.Name
            Catch ex As
Exception
            End
Try
        End If

        If (String.IsNullOrEmpty(displayText) = True) Then
            displayText =
"[Folder]"
        End If

        Return displayText
    End Function

    Protected Overrides Function CreateCollectionForm() As System.ComponentModel.Design.CollectionEditor.CollectionForm
        Dim frm As CollectionEditor.CollectionForm = MyBase
.CreateCollectionForm()
        frm.Font =
New Font("Tahoma"
, 8.25!)
        frm.Text =
"Edit Folders"
        frm.HelpButton = False

        'TableLayoutPanel: overArchingTableLayoutPanel
        '    Button: downButton
        '    TableLayoutPanel: addRemoveTableLayoutPanel
        '        Label: propertiesLabel
        '        Label: membersLabel
        '        FilterListBox: ListBox
        '        VsPropertyGrid: propertyBrowser
        '        TableLayoutPanel: okCancelTableLayoutPanel
        '        Button: upButton

        Dim overArchingTableLayoutPanel As TableLayoutPanel = frm.Controls.Item("overArchingTableLayoutPanel")
        If (Not overArchingTableLayoutPanel Is Nothing)
Then
            Dim propertyBrowser As PropertyGrid = overArchingTableLayoutPanel.Controls.Item("propertyBrowser"
)
            If (Not propertyBrowser Is Nothing)
Then
                propertyBrowser.PropertySort = PropertySort.Alphabetical
                propertyBrowser.ToolbarVisible =
False
            End
If
        End If

        'For Each ctrl As Control In frm.Controls.Item("overArchingTableLayoutPanel").Controls
        '    Debug.WriteLine(ctrl.Name, ctrl.GetType().Name)
        'Next

        Return frm
    End
Function

    ''' <summary>
    ''' Gets the list of items to fill the editor.
    '''
</summary>
    ''' <param name="editValue">The source property
</param>
    ''' <returns>Returns an IList items to populate the collection editor with.
</returns>
    Protected Overrides Function GetItems(ByVal editValue As Object) As Object
()
        'MsgBox(editValue.GetType().Name, , "GetItems")
        Dim lst As New Generic.List(Of
FolderPath)
        For Each path As String In
editValue
            lst.Add(
New
FolderPath(path))
        Next
        Return
lst.ToArray()
    End Function

    ''' <summary>
    ''' Takes the items from the editor and reapplies them to the source property.
    '''
</summary>
    ''' <param name="editValue">The source property
</param>
    ''' <param name="value">List of items from the editor.
</param>
    Protected Overrides Function SetItems(ByVal editValue As Object, ByVal value() As Object) As
Object
        'MsgBox(editValue.GetType().Name & ", " & value.GetType().Name, , "SetItems")
        Dim values As New Generic.List(Of String
)
        Dim uniquity As New Generic.List(Of String
)
        For i As Integer = 0 To
value.Length - 1
            Dim o As Object
= value(i)
            Dim path As String = String
.Empty
            If TypeOf o Is String
Then
                path = CStr
(o)
            ElseIf TypeOf o Is FolderPath
Then
                path = CType
(o, FolderPath).Path
            End
If
            If (String.IsNullOrEmpty(path) = False)
Then
                If (uniquity.Contains(path.ToLower()) = False)
Then
                    uniquity.Add(path.ToLower())
                    values.Add(path)
                End
If
            End
If
        Next
        Return MyBase
.SetItems(editValue, values.ToArray())
    End
Function

End
Class

Public

Class FolderPath

    Private
_path As String = String.Empty

    <Editor(
GetType(PathEditor), GetType
(UITypeEditor))> _
    Public Property Path() As
String
        Get
            Return Me
._path
        End
Get
        Set(ByVal Value As String
)
            If (String.IsNullOrEmpty(Value) = True) Then Value = String
.Empty
            Me
._path = Value
        End
Set
    End
Property
    Private Function ShouldSerializePath() As
Boolean
        Return
False
    End
Function
    Private Sub
ResetPath()
        Me.Path = String
.Empty
    End Sub

    Public Sub New()
    End Sub

    Public Sub New(ByVal path As String)
        MyClass
.New()
        Me
.Path = path
    End
Sub

End

Class

Public

Class PathEditor
    Inherits
UITypeEditor

    Public Sub New
()
        MyBase
.New()
    End
Sub

    Public Overrides Function EditValue(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal provider As System.IServiceProvider, ByVal value As Object) As
Object
        Dim path As String = CStr
(value)
        Dim dlg As New
FolderBrowserDialog
        dlg.SelectedPath = path
        dlg.Description =
"Select folder"
        Dim res As
DialogResult = DialogResult.Cancel
        res = dlg.ShowDialog()
        If (res = DialogResult.OK)
Then
            path = dlg.SelectedPath
        End
If
        Return
path
    End Function

    Public Overrides Function GetEditStyle(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.Drawing.Design.UITypeEditorEditStyle
        Return
UITypeEditorEditStyle.Modal
    End
Function

End

Class
 
Reply all
Reply to author
Forward
0 new messages