【问题标题】:I need an 'Open folder' dialog with possibility to manually enter path我需要一个可以手动输入路径的“打开文件夹”对话框
【发布时间】:2013-10-30 08:57:25
【问题描述】:

我使用 FileCtrl.SelectDirectory 来显示“打开文件夹”对话框。但是,我对此不满意,因为它不允许用户输入从何处开始浏览的路径。 例如,如果用户已经在剪贴板中有路径,它应该能够将它输入到我的对话框中,而不是浪费 12 秒来导航(打开)许多文件夹,直到它到达那里。

我发现this 代码似乎与 FileCtrl.SelectDirectory 完全一样。我希望它能让我更多地配置对话框。没有。

那么,如何在 SelectDirectory 中显示用户可以输入路径的编辑框?

我现在的解决方案是我自己的对话框。它是使用 TDirectory 和 TListBox 从零开始构建的。非常便利。但是它看起来很陈旧,因为它使用了 Embarcadero 的文件管理控件(TDirectory、TListBox),而且我们都知道它们看起来有多枯燥。


明确一点:我想要 FileCtrl.SelectDirectory 之类的东西,但有一个精确的 TEdit 或一个用户可以在其中输入其路径(如果有的话)的 crumbar。 示例:

【问题讨论】:

  • 您可以使用directory selection mode中的标准打开文件对话框。
  • 嗨安德烈亚斯 - 我可以这样做,但它的行为很糟糕。 'c:' 分支位于面板下方(底部)的某处。如果我双击它开始浏览过程,打开的分支会在屏幕外或非常靠近底部打开,因此用户必须拖动滚动条才能使所有这些分支可见。最糟糕的是,每次我打开一个新的子分支时,整个东西都会向下移动(再次移出屏幕),因此用户必须再次滚动。
  • davea 在下面给出了正确答案,但不幸的是他删除了它。
  • 在这里查看我对此的回答:stackoverflow.com/questions/7422689/…。虽然它没有编辑框,但也许它会给你一个起点?
  • 我会立即寻求设计自己的文件夹选择器对话框的机会,因为我已经做了几次不同的事情。使用 Windows API 查询磁盘驱动器及其文件夹结构相当简单。我使用树视图来允许用户浏览目录,其中包含我自己定制的所有代码。我还没有把它变成一个真正的发布对话框。

标签: delphi


【解决方案1】:

将 sdShowEdit 传递给 FileCtrl.SelectDirectory 会添加一个编辑框,您可以将目录粘贴到其中。

  FileCtrl.SelectDirectory('Caption', 'C:\', Dir, [sdNewUI, sdShowEdit]);

【讨论】:

  • 这是解决方案。 (尝试使用和不使用sdNewUI。据我所知,两者都可以正常工作。)
  • 我有点困惑。我删除了这个答案,因为我不相信它完全回答了这个问题。它在 SelectDirectory 中显示了一个“编辑框,用户可以在其中输入路径”,但正如 Altar 指出的那样,它不会“允许用户输入开始浏览的路径”。
  • @davea:公平点。不过,尚不清楚这是否是问题中最重要的部分。可能是这样。
  • @AndreasRejbrand-是的,用户应该能够编辑路径。
  • @AndreasRejbrand - 我错过了 sdShowEdit 参数。
【解决方案2】:

如果您使用具有Root 参数的SelectDirectory() 的重载版本,它会在内部调用SHBrowseForFolder()(另一个重载版本会显示自定义的VCL Win3.1 样式对话框)。如果将初始值分配给传递给Directory 参数的变量,它将作为初始选定文件夹传递给SHBrowseForFolder()。您还可以在Options 参数中指定sdShowEdit 标志。但是,编辑框并不用于输入完整路径。但是,如果你直接调用SHBrowseForFolder(),你可以为它提供你自己的回调函数,所以当对话框向你发送一个BFFM_VALIDATEFAILED事件时,你可以从对话框的编辑框中获取文本并发送对话框窗口一个BFFM_SETSELECTION 消息导航到正确的路径。

您真正需要的是 Vista+ IFileDialog 对话框提供的自定义设置。您可以使用IFileDialogCustomize 接口将自定义控件添加到对话框中,例如编辑框和按钮,然后实现IFileDialogControlEvents 接口以了解这些控件何时发生各种操作,例如按钮单击。您可以使用它来检查您的自定义编辑框或剪贴板中的有效路径,如果检测到,则通过IFileDialog.SetFolder() 方法告诉对话框导航到该路径。

【讨论】:

  • Nooo... 我不想务实地选择开始文件夹。我想让用户跳转到一个文件夹(例如,如果他在剪贴板中有路径)而不是一路浏览:)
  • 如果用户在剪贴板中有路径,您可以在打开对话框之前检测到并使用该路径打开它
  • 但是如果用户在剪贴板上有一个路径但不想浏览到该路径怎么办?
  • 提示用户-“在剪贴板上检测到路径,您想从该路径开始吗?” :)
  • 如果用户不想通过路径或没有路径可以过去,则不会。它将保留“路径”面包屑栏原样。
【解决方案3】:

Jedi VCS 的 TJvDirectoryEdit 做到了这一点。查一下。

以下是它的一些图片:

【讨论】:

  • 我不喜欢 Jedi 包裹。我在2-3年前尝试过。太大,太纠结,太不稳定。
  • @Altar 我从来没有遇到过 Jedi VCS 的任何问题。这是它的样子:imgur.com/a/SYrys
  • 但是在你的截图中我没有看到允许用户输入路径的编辑框!!!!!!
  • @Altar 文件夹名称所在的编辑框是可编辑的。你可以在我的第一个屏幕截图中看到我实际上写了“我正在编辑这个”。因此用户可以编写路径(或从剪贴板粘贴)或...使用“浏览文件夹”对话框选择它。
  • 它绝对不能回答我的具体问题,但解决方案很好。 +1
【解决方案4】:

如果我理解正确,我认为这可能是您的解决方案。

 procedure TForm1.Button1Click(Sender: TObject);
 var
  opendialog : Topendialog;
 begin
   openDialog := TOpenDialog.Create(self);
   openDialog.InitialDir := GetCurrentDir; {This can also be what is on the clipboard}
   openDialog.Options := [ofFileMustExist];
   openDialog.Filter := 'Text Document |*.txt'; {This is the type of file the user must open}
   openDialog.FilterIndex := 1;
   opendialog.execute;
end;

此代码创建并显示一个简单的打开对话框。 然后用户选择的路径是:

opendialog.filename

【讨论】:

  • 不,这将选择文件,而不是目录。 [此外,您还有内存泄漏。]
  • 所以我确实误解了你的问题对不起。
【解决方案5】:

@davea 的回答还可以,但它只显示旧的 (WinXP) 对话框样式。

所以,这是我现在使用的代码。在 Win Vista 及更高版本上,它显示新样式对话框和 Win XP 上的旧样式:

{$WARN SYMBOL_PLATFORM OFF}
{$IFDEF MSWindows}

function SelectAFolder(VAR Folder: string; CONST Options: TFileDialogOptions= [fdoPickFolders, fdoForceFileSystem, fdoPathMustExist, fdoDefaultNoMiniMode]): Boolean;   { Keywords: FolderDialog, BrowseForFolder}    { Works with UNC paths }
VAR Dlg: TFileOpenDialog;
begin
 { Win Vista and up }
 if OS_IsWindowsVistaUp then
  begin
   Dlg:= TFileOpenDialog.Create(NIL);   { Class for Vista and newer Windows operating systems style file open dialogs }
    TRY
      Dlg.Options       := Options;         
      Dlg.DefaultFolder := Folder;
      Dlg.FileName      := Folder;
      Result            := Dlg.Execute;
      if Result
      then Folder:= Dlg.FileName;
    FINALLY
      FreeAndNil(Dlg);
    END;
  end
 else
   { Win XP or down }
   Result:= vcl.FileCtrl.SelectDirectory('', ExtractFileDrive(Folder), Folder, [sdNewUI, sdShowEdit, sdNewFolder], nil);

 if Result
 then Folder:= Trail(Folder);
end;
{$ENDIF}
{$WARN SYMBOL_PLATFORM On}

{ Keywords: FolderDialog, BrowseForFolder}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    • 2015-10-22
    • 2018-02-12
    相关资源
    最近更新 更多