使用 CommonOpenFileDialog select 文件夹,但仍显示 Windows 文件夹中的文件 10
Using a CommonOpenFileDialog to select a folder but still show files within the folder in Windows 10
我正在尝试使用 CommonOpenFileDialog
来允许用户 select 一个文件夹,而且还可以在对话框中查看该文件夹内的文件。目前我的代码只允许用户 select 一个文件夹,但其中的文件是隐藏的,这导致用户认为他们 select 输入了错误的(空)文件夹。
using (var dlg = new CommonOpenFileDialog()
{
Title = "Select folder to import from",
AllowNonFileSystemItems = true,
IsFolderPicker = true,
EnsurePathExists = true,
Multiselect = false,
ShowPlacesList = true
})
{
if (dlg.ShowDialog() == CommonFileDialogResult.Ok)
{
//Do things with the selected folder and the files within it...
}
}
我如何才能实现面向 Windows 10 岁的应用程序的目标?
注意: 有一个非常相似的问题,标题为“How can I make CommonOpenFileDialog select folders only, but still show files?”。这个问题已经有了很好的答案,但是,none 的解决方案适用于 Windows 10。因为现有问题已经过时(9 年前提出)并且不适用于 Windows 10,所以这个问题专门要求在 Windows 10 设备上工作的解决方案。
我认为 CommonOpenFileDialog 无法做到这一点
参见:How to use IFileDialog with FOS_PICKFOLDER while still displaying file names in the dialog
唯一的方法是创建您自己的自定义对话框,或者您可以使用带 P/Invoke 的文件夹对话框(基于 SHBrowseForFolder,如 FolderBrowserDialog
)。
参见:http://www.pinvoke.net/default.aspx/shell32.shbrowseforfolder
复制上面 link 中的 class 并添加选项 BIF_BROWSEINCLUDEFILES
.
public string SelectFolder(string caption, string initialPath, IntPtr parentHandle)
{
_initialPath = initialPath;
...
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_SHAREABLE | BIF_BROWSEINCLUDEFILES;
不幸的是,现在对话框中的文件只显示为 FolderBrowserDialog
。
是否可以使用类似的东西?处理 FolderChanging
事件并读取文件夹名称?
private string SelectFolder()
{
using (var dlg = new CommonOpenFileDialog()
{
Title = "Select folder to import from",
AllowNonFileSystemItems = true,
IsFolderPicker = true,
EnsurePathExists = true,
Multiselect = false,
ShowPlacesList = true,
InitialDirectory = "C:\" //This must be handled manually
})
{
dlg.FolderChanging += Dlg_FolderChanging;
if (dlg.ShowDialog() == CommonFileDialogResult.Ok)
{
//Do things with the selected folder and the files within it...
string selectedFolder = dlg.InitialDirectory;
string dlgFileName = dlg.FileName;
if (Directory.Exists(dlgFileName))
selectedFolder = dlgFileName;
else if (File.Exists(dlgFileName))
selectedFolder = Path.GetDirectoryName(dlgFileName);
else if (string.IsNullOrWhiteSpace(lastKnownFolder))
selectedFolder = lastKnownFolder;
return selectedFolder;
}
}
return null;
}
private string lastKnownFolder = "";
private void Dlg_FolderChanging(object sender, CommonFileDialogFolderChangeEventArgs e)
{
lastKnownFolder = e.Folder;
}
我正在尝试使用 CommonOpenFileDialog
来允许用户 select 一个文件夹,而且还可以在对话框中查看该文件夹内的文件。目前我的代码只允许用户 select 一个文件夹,但其中的文件是隐藏的,这导致用户认为他们 select 输入了错误的(空)文件夹。
using (var dlg = new CommonOpenFileDialog()
{
Title = "Select folder to import from",
AllowNonFileSystemItems = true,
IsFolderPicker = true,
EnsurePathExists = true,
Multiselect = false,
ShowPlacesList = true
})
{
if (dlg.ShowDialog() == CommonFileDialogResult.Ok)
{
//Do things with the selected folder and the files within it...
}
}
我如何才能实现面向 Windows 10 岁的应用程序的目标?
注意: 有一个非常相似的问题,标题为“How can I make CommonOpenFileDialog select folders only, but still show files?”。这个问题已经有了很好的答案,但是,none 的解决方案适用于 Windows 10。因为现有问题已经过时(9 年前提出)并且不适用于 Windows 10,所以这个问题专门要求在 Windows 10 设备上工作的解决方案。
我认为 CommonOpenFileDialog 无法做到这一点
参见:How to use IFileDialog with FOS_PICKFOLDER while still displaying file names in the dialog
唯一的方法是创建您自己的自定义对话框,或者您可以使用带 P/Invoke 的文件夹对话框(基于 SHBrowseForFolder,如 FolderBrowserDialog
)。
参见:http://www.pinvoke.net/default.aspx/shell32.shbrowseforfolder
复制上面 link 中的 class 并添加选项 BIF_BROWSEINCLUDEFILES
.
public string SelectFolder(string caption, string initialPath, IntPtr parentHandle)
{
_initialPath = initialPath;
...
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_SHAREABLE | BIF_BROWSEINCLUDEFILES;
不幸的是,现在对话框中的文件只显示为 FolderBrowserDialog
。
是否可以使用类似的东西?处理 FolderChanging
事件并读取文件夹名称?
private string SelectFolder()
{
using (var dlg = new CommonOpenFileDialog()
{
Title = "Select folder to import from",
AllowNonFileSystemItems = true,
IsFolderPicker = true,
EnsurePathExists = true,
Multiselect = false,
ShowPlacesList = true,
InitialDirectory = "C:\" //This must be handled manually
})
{
dlg.FolderChanging += Dlg_FolderChanging;
if (dlg.ShowDialog() == CommonFileDialogResult.Ok)
{
//Do things with the selected folder and the files within it...
string selectedFolder = dlg.InitialDirectory;
string dlgFileName = dlg.FileName;
if (Directory.Exists(dlgFileName))
selectedFolder = dlgFileName;
else if (File.Exists(dlgFileName))
selectedFolder = Path.GetDirectoryName(dlgFileName);
else if (string.IsNullOrWhiteSpace(lastKnownFolder))
selectedFolder = lastKnownFolder;
return selectedFolder;
}
}
return null;
}
private string lastKnownFolder = "";
private void Dlg_FolderChanging(object sender, CommonFileDialogFolderChangeEventArgs e)
{
lastKnownFolder = e.Folder;
}