是否有“简单”的方法从同一个对话框中选择文件或文件夹?
在我创建的许多应用中,我允许将文件或文件夹作为输入。 到目前为止,我总是最终创建一个开关,在文件或文件夹选择对话框之间切换,或者只使用拖放功能。
由于这似乎是一个基本的东西我想象之前已经创建过,但谷歌搜索不会产生太多信息。所以看起来我需要从头开始创建一个自定义选择对话框,但我宁愿不通过重新发明轮子来完成这样一个简单的任务来引入任何问题。
任何人有任何提示或现有解决方案吗?
为了保持UI的一致性,如果可以扩展OpenFileDialog(或FolderBrowserDialog),那就太好了。
答案 0 :(得分:12)
从技术上讲,这是可能的。 FolderBrowseDialog使用的shell对话框能够返回文件和文件夹。不幸的是,该功能未在.NET中公开。甚至反射都不会激活所需的选项标记。
要使其正常工作,您必须在BROWSEINFO.ulFlags(值= 0x4000)中打开BIF_BROWSEINCLUDEFILES标志的P / Invoke SHBrowseForFolder()。 P / Invoke是坚韧不拔的,最好使用Reflector的帮助来复制和粘贴another source或FolderBrowseDialog类本身的代码。
答案 1 :(得分:7)
基于以上提示,我找到了一些在以下位置使用标准文件夹浏览器对话框的工作代码: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
答案 2 :(得分:5)
已经完成了。你可以使用FolderBrowserDialogEx - 内置FolderBrowserDialog的可重用衍生物。这个允许您输入路径,甚至是UNC路径。您可以浏览文件夹或文件+文件夹。您可以使用它浏览计算机或打印机。基于内置的FBD,但......更好。更灵活。如果单击GUI中的文件夹,则路径将显示在文本框中。如果您键入路径,该文件夹将被激活。内置对话框缺少许多选项。
完整源代码。自由。 MS-Public许可证。
使用它的代码:
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;
}
答案 3 :(得分:5)
您可以使用标准的OpenFileDialog来选择文件夹。这是CodeProject中的一篇文章,演示了一种方法(http://www.codeproject.com/KB/dialog/OpenFileOrFolderDialog.aspx)。
答案 4 :(得分:1)
AFAIK,.NET框架中没有任何东西能够开箱即用。
.NET文件对话框派生自CommonDialog:
需要继承的类 通过调用实现RunDialog ShowDialog创建一个特定的常见 对话框。继承的类可以 覆盖HookProc来实现 特定对话框钩子 功能。
答案 5 :(得分:1)
所有内置对话框都使用与其动作,PrintDialog,OpenFileDialog,SaveFileDialog等对应的shell API ...
您很可能必须手动构建此功能。
答案 6 :(得分:1)
http://www.pinvoke.net/default.aspx/shell32.shbrowseforfolder
如果您更改此示例
,则此处为gerat链接 bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_SHAREABLE;
代表
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_SHAREABLE | BIF_BROWSEINCLUDEFILES;
你会得到你想要的东西
答案 7 :(得分:0)
如果您只想显示特定的文件类型,以下article(包含C#中的源代码)可以帮助您:
它还解释了可用于“自定义”FolderBrowser对话框的其他选项
答案 8 :(得分:0)
这将允许您使用OpenFileDialog
选择文件夹 openFileDialog1.CheckFileExists = false;
openFileDialog1.ValidateNames = false;
答案 9 :(得分:0)
Ookii Dialogs 实现文件夹浏览器对话框,该对话框允许将文件或文件夹作为输入,并且可用于Windows窗体和WPF。
Ookii.Dialogs.Wpf
Ookii.Dialogs.WinForms