In my application, I have a property that takes a icon file path, another property that can take a file or folder, and other property that takes a folder path.
So, I had to write variations for each one of these properties...
The easiest one, and in case of you are satisfied with the FolderBrowserDialog
appearance and limitations, then is to directly specify the System.Windows.Forms.Design.FolderNameEditor
class in the EditorAttribute
class. Otherwise, Ooki.Dialogs is a good open-source library as an alternative to get a modern-look dialog.
The second easiest one is the editor for selecting a icon file path:
''' <summary>
''' Provides a user interface for selecting a icon file name.
''' </summary>
''' <seealso cref="FileNameEditor"/>
Friend Class IconFileNameEditor : Inherits FileNameEditor
#Region " Constructors "
''' <summary>
''' Initializes a new instance of the <see cref="IconFileNameEditor"/> class.
''' </summary>
Public Sub New()
MyBase.New()
End Sub
#End Region
#Region " Private Methods "
''' <summary>
''' Initializes the open file dialog when it is created.
''' </summary>
''' <param name="ofd">
''' The <see cref="OpenFileDialog"/> to use to select a file name.
''' </param>
Protected Overrides Sub InitializeDialog(ByVal dlg As OpenFileDialog)
MyBase.InitializeDialog(dlg)
With dlg
.Multiselect = False
.RestoreDirectory = True
.DereferenceLinks = True
.Filter = "Icon Files (*.ico;*.icl;*.exe;*.dll)|*.ico;*.icl;*.exe;*.dll|Icons|*.ico|Libraries|*.dll|Programs|*.exe"
.FilterIndex = 1
.SupportMultiDottedExtensions = True
End With
End Sub
#End Region
End Class
For selecting a file path or folder path, and in search of something already done and open-source in order to avoid adding external dependancies to my project, I took a custom FileFolderDialog
class provided in this article, and I managed to write the editor like this:
''' <summary>
''' Provides a user interface for selecting a file or folder name.
''' </summary>
''' <seealso cref="UITypeEditor"/>
Public Class FileOrFolderNameEditor : Inherits UITypeEditor
#Region " Constructors "
''' <summary>
''' Initializes a new instance of the <see cref="FileOrFolderNameEditor"/> class.
''' </summary>
Public Sub New()
MyBase.New()
End Sub
#End Region
#Region " Public Methods"
''' <summary>
''' Gets the editor style used by the <see cref="UITypeEditor.EditValue(IServiceProvider, Object)"/> method.
''' </summary>
''' <param name="context">
''' An <see cref="ITypeDescriptorContext"/> that can be used to gain additional context information.
''' </param>
''' <returns>
''' A <see cref="UITypeEditorEditStyle"/> value that indicates the style of editor used
''' by the <see cref="UITypeEditor.EditValue(IServiceProvider, Object)"/> method.
''' <para></para>
''' If the <see cref="UITypeEditor"/> does not support this method,
''' then <see cref="UITypeEditor.GetEditStyle"/> will return <see cref="UITypeEditorEditStyle.None"/>.
''' </returns>
Public Overrides Function GetEditStyle(ByVal context As ITypeDescriptorContext) As UITypeEditorEditStyle
Return UITypeEditorEditStyle.Modal
End Function
''' <summary>
''' Edits the specified object's value using the editor style indicated by the <see cref="UITypeEditor.GetEditStyle"/> method.
''' </summary>
''' <param name="context">
''' An <see cref="ITypeDescriptorContext"/> that can be used to gain additional context information.
''' </param>
''' <param name="provider">
''' An <see cref="IServiceProvider"/> that this editor can use to obtain services.
''' </param>
''' <param name="value">
''' The object to edit.
''' </param>
''' <returns>
''' The new value of the object.
''' <para></para>
''' If the value of the object has not changed, this should return the same object it was passed.
''' </returns>
Public Overrides Function EditValue(ByVal context As ITypeDescriptorContext, ByVal provider As IServiceProvider, ByVal value As Object) As Object
Using dlg As New OpenFileOrFolderDialog()
If (dlg.ShowDialog = DialogResult.OK) Then
Return dlg.SelectedPath
End If
End Using
Return MyBase.EditValue(context, provider, value)
End Function
#End Region
End Class
It was pretty easy at all.