问题
I have a custom control with a property that holds the name (full path) to a file location that exists on the target computer.
The exact path will vary according to type of target pc and is typically set right after I add the custom control to my Form, while I am still in design mode of my project, so that when my application runs, it picks up the filename from the property.
It would be convenient if the property opened a file dialog to let me browse to the location (similar to how dialogs are opened when browsing for image and color properties), but this doesn't seem to be possible in visual basic.
After googling for days I have found a couple of articles that touch the subject for other programming languages (see example snippet below) but I haven't been able to work out how to make it work for visual basic.
Here is a snippet I found that mentions the use of an editor, which may be a clue to get started.
[Editor(typeof(FileSelectorTypeEditor), typeof(UITypeEditor))]
public string Filename
{
get { return _filename; }
set { _filename = value; }
}
Hope someone out there can lead me in the right way.
回答1:
FileSelectorTypeEditor
is probably a custom class derived from either FileNameEditor or FolderNameEditor.
You can implement both, using the standard class or extend the default with your own, as you have seen in those C# sources you have found.
Here I'm using a specialized FileNameEditor
class, named (with some lack of imagination) SpecializedFileNameEditor
and the standard FolderNameEditor
assigning the UITypeEditor
to two properties of a class.
► The ImagePath
property editor is the SpecializedFileNameEditor
object, which uses an OpenFileDialog, where a filter is pre-selected. It also overrides the EditValue
method, to set the current value, if any, of an associated property (here, ImagePath
) as the InitialDirectory of the OpenFileDialog.
► The ImageFolder
property editor is a standard FolderNameEditor
, which opens a FolderBrowserDialog.
I'm also attaching an ExpandableObjectConverter type converter, so you can present the two properties as an expandable property selector in a PropertyGrid.
You can see an example here:
How to bind child Controls of a User Control to a Public Property
Imports System.ComponentModel
Imports System.Drawing.Design
Imports System.IO
Imports System.Windows.Forms
Imports System.Windows.Forms.Design
<TypeConverter(GetType(ExpandableObjectConverter))>
Public Class ImagePickerClass
Public Sub New()
' Initialize [...]
End Sub
<Editor(GetType(SpecializedFileNameEditor), GetType(UITypeEditor))>
Public Property ImagePath As String
<Editor(GetType(FolderNameEditor), GetType(UITypeEditor))>
Public Property ImageFolder As String
Public Class SpecializedFileNameEditor
Inherits FileNameEditor
Private currentValue As String = String.Empty
Public Overrides Function EditValue(context As ITypeDescriptorContext, provider As IServiceProvider, value As Object) As Object
If TypeOf value Is String Then
currentValue = DirectCast(value, String)
End If
Return MyBase.EditValue(context, provider, value)
End Function
Protected Overrides Sub InitializeDialog(ofd As OpenFileDialog)
MyBase.InitializeDialog(ofd)
If Not currentValue.Equals(String.Empty) Then
ofd.InitialDirectory = Path.GetDirectoryName(currentValue)
End If
ofd.Filter = "PNG Images (*.png)|*.png"
End Sub
End Class
End Class
来源:https://stackoverflow.com/questions/61677911/how-do-i-make-a-property-of-a-custom-control-open-a-file-dialog