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
Post by VisualHintHello Waldo,
if you want to get the true string collection editor, decorate your
[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
http://www.dotnet247.com/247reference/msgs/30/153300.aspx
The method CreateInstance of your editor must return an empty string.
Best regards,
Home of Smart FieldPackEditor.Net / DateTimePicker replacement
Home of Smart PropertyGrid for .Net and MFC
Microsoft PropertyGrid Resource List - http://www.propertygridresourcelist.com
Post by WALDOI 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
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