是否有"简单"的方法从同一对话框中选择文件或文件夹?
在我创建的许多应用程序中,我允许将文件或文件夹作为输入.到目前为止,我总是最终创建一个开关,在文件或文件夹选择对话框之间切换,或者只使用拖放功能.
因为这似乎是一个基本的东西我想象之前已经创建过,但谷歌搜索不会产生太多信息.因此看起来我需要从头开始创建一个自定义选择对话框,但我宁愿不通过重新发明轮子来执行这样一个简单的任务来引入任何问题.
有人提示或现有解决方案吗?
为了保持UI的一致性,如果可以扩展OpenFileDialog(或FolderBrowserDialog),那将是很好的.
从技术上讲,这是可能的.FolderBrowseDialog使用的shell对话框能够返回文件和文件夹.不幸的是,该功能未在.NET中公开.甚至反射都不能戳戳所需的选项标志.
为了使它工作,你必须在BROWSEINFO.ulFlags(值= 0x4000)中打开BIF_BROWSEINCLUDEFILES标志来P/Invoke SHBrowseForFolder().P/Invoke是坚韧不拔的,最好使用Reflector的帮助从其他源或FolderBrowseDialog类本身复制和粘贴代码.
基于以上提示,我发现了一些使用标准文件夹浏览器对话框的工作代码,位于以下位置:http://topic.csdn.net/t/20020703/05/845468.html
扩展文件夹浏览器对话框的类
Imports System Imports System.Text Imports System.Windows.Forms Imports System.Runtime.InteropServices Public Class DirectoryDialog Public Structure BROWSEINFO Public hWndOwner As IntPtr Public pIDLRoot As Integer Public pszDisplayName As String Public lpszTitle As String Public ulFlags As Integer Public lpfnCallback As Integer Public lParam As Integer Public iImage As Integer End Structure Const MAX_PATH As Integer = 260 Public Enum BrowseForTypes As Integer Computers = 4096 Directories = 1 FilesAndDirectories = 16384 FileSystemAncestors = 8 End Enum Declare Function CoTaskMemFree Lib "ole32" Alias "CoTaskMemFree" (ByVal hMem As IntPtr) As Integer Declare Function lstrcat Lib "kernel32" Alias "lstrcat" (ByVal lpString1 As String, ByVal lpString2 As String) As IntPtr Declare Function SHBrowseForFolder Lib "shell32" Alias "SHBrowseForFolder" (ByRef lpbi As BROWSEINFO) As IntPtr Declare Function SHGetPathFromIDList Lib "shell32" Alias "SHGetPathFromIDList" (ByVal pidList As IntPtr, ByVal lpBuffer As StringBuilder) As Integer Protected Function RunDialog(ByVal hWndOwner As IntPtr) As Boolean Dim udtBI As BROWSEINFO = New BROWSEINFO() Dim lpIDList As IntPtr Dim hTitle As GCHandle = GCHandle.Alloc(Title, GCHandleType.Pinned) udtBI.hWndOwner = hWndOwner udtBI.lpszTitle = Title udtBI.ulFlags = BrowseFor Dim buffer As StringBuilder = New StringBuilder(MAX_PATH) buffer.Length = MAX_PATH udtBI.pszDisplayName = buffer.ToString() lpIDList = SHBrowseForFolder(udtBI) hTitle.Free() If lpIDList.ToInt64() <> 0 Then If BrowseFor = BrowseForTypes.Computers Then m_Selected = udtBI.pszDisplayName.Trim() Else Dim path As StringBuilder = New StringBuilder(MAX_PATH) SHGetPathFromIDList(lpIDList, path) m_Selected = path.ToString() End If CoTaskMemFree(lpIDList) Else Return False End If Return True End Function Public Function ShowDialog() As DialogResult Return ShowDialog(Nothing) End Function Public Function ShowDialog(ByVal owner As IWin32Window) As DialogResult Dim handle As IntPtr If Not owner Is Nothing Then handle = owner.Handle Else handle = IntPtr.Zero End If If RunDialog(handle) Then Return DialogResult.OK Else Return DialogResult.Cancel End If End Function Public Property Title() As String Get Return m_Title End Get Set(ByVal Value As String) If Value Is DBNull.Value Then Throw New ArgumentNullException() End If m_Title = Value End Set End Property Public ReadOnly Property Selected() As String Get Return m_Selected End Get End Property Public Property BrowseFor() As BrowseForTypes Get Return m_BrowseFor End Get Set(ByVal Value As BrowseForTypes) m_BrowseFor = Value End Set End Property Private m_BrowseFor As BrowseForTypes = BrowseForTypes.Directories Private m_Title As String = "" Private m_Selected As String = "" Public Sub New() End Sub End Class
实现扩展对话框的代码
Sub Button1Click(ByVal sender As Object, ByVal e As EventArgs) Dim frmd As DirectoryDialog = New DirectoryDialog() ' frmd.BrowseFor = DirectoryDialog.BrowseForTypes.Directories ' frmd.BrowseFor = DirectoryDialog.BrowseForTypes.Computers frmd.BrowseFor = DirectoryDialog.BrowseForTypes.FilesAndDirectories frmd.Title = "Select a file or a folder" If frmd.ShowDialog(Me) = DialogResult.OK Then MsgBox(frmd.Selected) End If End Sub
它已经完成了.您可以使用FolderBrowserDialogEx - 内置FolderBrowserDialog的可重用衍生物.这个允许您输入路径,甚至是UNC路径.您可以浏览文件夹或文件+文件夹.您可以使用它浏览计算机或打印机.基于内置的FBD,但......更好.更灵活.如果单击GUI中的文件夹,则路径将显示在文本框中.如果您键入路径,该文件夹将被激活.内置对话框缺少许多选项.
完整源代码.自由.MS-Public许可证.
FolderBrowserDialogEx http://www.freeimagehosting.net/uploads/bfbab6cea5.png
使用它的代码:
var dlg1 = new Ionic.Utils.FolderBrowserDialogEx(); dlg1.Description = "Select a folder to extract to:"; dlg1.ShowNewFolderButton = true; dlg1.ShowEditBox = true; //dlg1.NewStyle = false; dlg1.SelectedPath = txtExtractDirectory.Text; dlg1.ShowFullPathInEditBox = true; dlg1.RootFolder = System.Environment.SpecialFolder.MyComputer; // Show the FolderBrowserDialog. DialogResult result = dlg1.ShowDialog(); if (result == DialogResult.OK) { txtExtractDirectory.Text = dlg1.SelectedPath; }
您可以使用标准OpenFileDialog来选择文件夹.这是CodeProject中的一篇文章,演示了一种方法(http://www.codeproject.com/KB/dialog/OpenFileOrFolderDialog.aspx).