Просмотр исходного кода

fix: 在长路径下,保存文件弹窗无法选择不存在的文件

龙腾猫跃 5 месяцев назад
Родитель
Сommit
d3dbc23003
1 измененных файлов с 22 добавлено и 23 удалено
  1. 22 23
      Wpf/General/Dialogs.cs

+ 22 - 23
Wpf/General/Dialogs.cs

@@ -1,32 +1,31 @@
-using System.Windows.Forms;
+using Microsoft.Win32;
 
 namespace MeloongCore.Wpf;
 
 public static class Dialogs {
 
     /// <summary>
-    /// 弹出 “保存” 弹窗,返回用户选择的路径(若取消则返回 <c>null</c>)。
+    /// 弹出 “保存” 弹窗,返回用户指定的路径,若取消则返回 <c>null</c>。
     /// <para/> <paramref name="filter"/> 中的扩展名不加 <c>.</c>。
     /// </summary>
     public static string? SaveFile(string title, string defaultFileName = "", string? defaultDirectory = null, IEnumerable<(string Extension, string Display)>? filter = null) {
         var filters = filter?.ToList();
-        using var dialog = new SaveFileDialog {
+        var dialog = new SaveFileDialog {
             AddExtension = true,
-            AutoUpgradeEnabled = true,
             Title = title,
             FileName = defaultFileName
         };
-        if (!string.IsNullOrEmpty(defaultDirectory) && Directory.Exists(defaultDirectory)) dialog.InitialDirectory = PathUtils.ToShortPath(defaultDirectory!);
+        if (!string.IsNullOrEmpty(defaultDirectory) && DirectoryUtils.Exists(defaultDirectory!)) dialog.InitialDirectory = PathUtils.ToShortPath(defaultDirectory!);
         if (filters != null) {
             dialog.Filter = filters.Select(f => $"{f.Display}(*.{f.Extension})|*.{f.Extension}").Join("|");
         }
 
         Logger.Info($"保存弹窗:{dialog.Title}(FileName={dialog.FileName}, InitialDirectory={dialog.InitialDirectory}, Filter={dialog.Filter})");
-        dialog.ShowDialog();
+        if (dialog.ShowDialog() != true) return null;
 
         var result = dialog.FileName;
         Logger.Info($"保存弹窗返回:{result}");
-        if (!result.Contains('\\')) return null;
+        if (!result.Contains(Path.DirectorySeparatorChar)) return null;
         // AddExtension 可能失效,需要手动补全(#8214)
         if (filters != null && !string.IsNullOrEmpty(result) && !filters.Any(f => result.EndsWithF("." + f.Extension))) {
             result += "." + filters[dialog.FilterIndex - 1].Extension;
@@ -36,20 +35,19 @@ public static class Dialogs {
     }
 
     /// <summary>
-    /// 弹出 “选择文件” 弹窗,返回用户选择的文件路径(若取消则返回空数组)。
+    /// 弹出 “选择文件” 弹窗,返回用户选择的文件路径,若取消则返回空数组。
     /// <para/> <paramref name="filter"/> 中的扩展名不加 <c>.</c>。
     /// </summary>
-    public static string[] SelectFile(string title, bool multiselect, string? defaultDirectory = null, IEnumerable<(string[] Extensions, string Display)>? filter = null) {
+    public static List<string> SelectFile(string title, bool multiselect, string? defaultDirectory = null, IEnumerable<(string[] Extensions, string Display)>? filter = null) {
         var filters = filter?.ToList();
-        using var dialog = new OpenFileDialog {
+        var dialog = new OpenFileDialog {
             AddExtension = true,
-            AutoUpgradeEnabled = true,
             CheckFileExists = true,
             Multiselect = multiselect,
             Title = title,
             ValidateNames = true
         };
-        if (!string.IsNullOrEmpty(defaultDirectory) && Directory.Exists(defaultDirectory)) dialog.InitialDirectory = PathUtils.ToShortPath(defaultDirectory!);
+        if (!string.IsNullOrEmpty(defaultDirectory) && DirectoryUtils.Exists(defaultDirectory!)) dialog.InitialDirectory = PathUtils.ToShortPath(defaultDirectory!);
         if (filters != null) {
             dialog.Filter = filters.Select(f => {
                 var exts = string.Join(";", f.Extensions.Select(e => $"*.{e}"));
@@ -58,30 +56,31 @@ public static class Dialogs {
         }
 
         Logger.Info($"选择文件弹窗:{dialog.Title}(Multiselect={dialog.Multiselect}, InitialDirectory={dialog.InitialDirectory}, Filter={dialog.Filter})");
-        dialog.ShowDialog();
+        if (dialog.ShowDialog() != true) return [];
 
-        var results = multiselect ? dialog.FileNames : (string.IsNullOrEmpty(dialog.FileName) ? [] : [dialog.FileName]);
-        Logger.Info($"选择文件弹窗返回:{string.Join(",", results)}");
+        var results = dialog.FileNames.Where(f => f.Contains(Path.DirectorySeparatorChar)).ToList();
+        Logger.Info($"选择文件弹窗返回:{results.Join(",")}");
         return results;
     }
 
     /// <summary>
-    /// 弹出选取文件夹对话框,返回用户选择的文件夹路径(以 \ 结尾),取消则返回空字符串。
+    /// 弹出 “选择文件夹” 弹窗,返回用户选择的文件夹路径(以分隔符结尾),若取消则返回空数组。
     /// </summary>
-    public static string SelectFolder(string title, string? defaultDirectory = null) {
+    public static List<string> SelectFolder(string title, bool multiselect, string? defaultDirectory = null) {
         var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog {
             ShowNewFolderButton = true,
             Description = title,
+            Multiselect = multiselect,
             UseDescriptionForTitle = true
         };
-        if (!string.IsNullOrEmpty(defaultDirectory) && Directory.Exists(defaultDirectory)) dialog.SelectedPath = defaultDirectory;
+        if (!string.IsNullOrEmpty(defaultDirectory) && DirectoryUtils.Exists(defaultDirectory!)) dialog.SelectedPath = defaultDirectory;
 
-        Logger.Info($"选择文件夹弹窗:{dialog.Description}(SelectedPath={dialog.SelectedPath})");
-        dialog.ShowDialog();
+        Logger.Info($"选择文件夹弹窗:{dialog.Description}(Multiselect={dialog.Multiselect}, SelectedPath={dialog.SelectedPath})");
+        if (dialog.ShowDialog() != true) return [];
 
-        var result = string.IsNullOrEmpty(dialog.SelectedPath) ? "" : (dialog.SelectedPath!.EndsWithF('\\') ? dialog.SelectedPath! : dialog.SelectedPath! + '\\');
-        Logger.Info($"选择文件夹弹窗返回:{result}");
-        return result;
+        var results = dialog.SelectedPaths.Where(f => f.Contains(Path.DirectorySeparatorChar)).Select(PathUtils.AddSlashSuffix).ToList();
+        Logger.Info($"选择文件夹弹窗返回:{results.Join(",")}");
+        return results;
     }
 
 }