Dialogs.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using System.Windows.Forms;
  2. namespace MeloongCore.Wpf;
  3. public static class Dialogs {
  4. /// <summary>
  5. /// 弹出 “保存” 弹窗,返回用户选择的路径(若取消则返回 <c>null</c>)。
  6. /// <para/> <paramref name="filter"/> 中的扩展名不加 <c>.</c>。
  7. /// </summary>
  8. public static string? SaveFile(string title, string defaultFileName = "", string? defaultDirectory = null, IEnumerable<(string Extension, string Display)>? filter = null) {
  9. var filters = filter?.ToList();
  10. using var dialog = new SaveFileDialog {
  11. AddExtension = true,
  12. AutoUpgradeEnabled = true,
  13. Title = title,
  14. FileName = defaultFileName
  15. };
  16. if (!string.IsNullOrEmpty(defaultDirectory) && Directory.Exists(defaultDirectory)) dialog.InitialDirectory = PathUtils.ToShortPath(defaultDirectory!);
  17. if (filters != null) {
  18. dialog.Filter = filters.Select(f => $"{f.Display}(*.{f.Extension})|*.{f.Extension}").Join("|");
  19. }
  20. Logger.Info($"保存弹窗:{dialog.Title}(FileName={dialog.FileName}, InitialDirectory={dialog.InitialDirectory}, Filter={dialog.Filter})");
  21. dialog.ShowDialog();
  22. var result = dialog.FileName;
  23. Logger.Info($"保存弹窗返回:{result}");
  24. if (!result.Contains('\\')) return null;
  25. // AddExtension 可能失效,需要手动补全(#8214)
  26. if (filters != null && !string.IsNullOrEmpty(result) && !filters.Any(f => result.EndsWithF("." + f.Extension))) {
  27. result += "." + filters[dialog.FilterIndex - 1].Extension;
  28. Logger.Warn($"选择文件的返回无扩展名,将会手动添加,修改后为:{result}");
  29. }
  30. return result;
  31. }
  32. /// <summary>
  33. /// 弹出 “选择文件” 弹窗,返回用户选择的文件路径(若取消则返回空数组)。
  34. /// <para/> <paramref name="filter"/> 中的扩展名不加 <c>.</c>。
  35. /// </summary>
  36. public static string[] SelectFile(string title, bool multiselect, string? defaultDirectory = null, IEnumerable<(string[] Extensions, string Display)>? filter = null) {
  37. var filters = filter?.ToList();
  38. using var dialog = new OpenFileDialog {
  39. AddExtension = true,
  40. AutoUpgradeEnabled = true,
  41. CheckFileExists = true,
  42. Multiselect = multiselect,
  43. Title = title,
  44. ValidateNames = true
  45. };
  46. if (!string.IsNullOrEmpty(defaultDirectory) && Directory.Exists(defaultDirectory)) dialog.InitialDirectory = PathUtils.ToShortPath(defaultDirectory!);
  47. if (filters != null) {
  48. dialog.Filter = filters.Select(f => {
  49. var exts = string.Join(";", f.Extensions.Select(e => $"*.{e}"));
  50. return $"{f.Display}({exts})|{exts}";
  51. }).Join("|");
  52. }
  53. Logger.Info($"选择文件弹窗:{dialog.Title}(Multiselect={dialog.Multiselect}, InitialDirectory={dialog.InitialDirectory}, Filter={dialog.Filter})");
  54. dialog.ShowDialog();
  55. var results = multiselect ? dialog.FileNames : (string.IsNullOrEmpty(dialog.FileName) ? [] : [dialog.FileName]);
  56. Logger.Info($"选择文件弹窗返回:{string.Join(",", results)}");
  57. return results;
  58. }
  59. /// <summary>
  60. /// 弹出选取文件夹对话框,返回用户选择的文件夹路径(以 \ 结尾),取消则返回空字符串。
  61. /// </summary>
  62. public static string SelectFolder(string title, string? defaultDirectory = null) {
  63. var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog {
  64. ShowNewFolderButton = true,
  65. Description = title,
  66. UseDescriptionForTitle = true
  67. };
  68. if (!string.IsNullOrEmpty(defaultDirectory) && Directory.Exists(defaultDirectory)) dialog.SelectedPath = defaultDirectory;
  69. Logger.Info($"选择文件夹弹窗:{dialog.Description}(SelectedPath={dialog.SelectedPath})");
  70. dialog.ShowDialog();
  71. var result = string.IsNullOrEmpty(dialog.SelectedPath) ? "" : (dialog.SelectedPath!.EndsWithF('\\') ? dialog.SelectedPath! : dialog.SelectedPath! + '\\');
  72. Logger.Info($"选择文件夹弹窗返回:{result}");
  73. return result;
  74. }
  75. }