Dialogs.cs 4.3 KB

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