SaveFileDialog AddExtension无法正常工作 [英] SaveFileDialog AddExtension doesn't work as expected

查看:123
本文介绍了SaveFileDialog AddExtension无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下C#代码,该代码正在使用

I've the following C# code, which is using the SaveFileDialog and set's the AddExtension property to true:

var dialog = new SaveFileDialog();
dialog.AddExtension = true;
dialog.DefaultExt = "txt";
dialog.Filter = "Text files (*.txt)|*.txt|XML files (*.xml)|*.xml";
dialog.OverwritePrompt = true;
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
    label1.Text = dialog.FileName;
}

我已经测试了对话框的File nameSave as type的以下组合.

And I've tested the following combination of File name and Save as type of the dialog.

File name       | Save as type   | label1.Text    | What I expect
----------------+----------------+----------------+----------------
test1           | *.txt          | test1.txt      | test1.txt
test2.txt       | *.txt          | test2.txt      | test2.txt
test3.abc       | *.txt          | test3.abc.txt  | test3.abc.txt
test4           | *.xml          | test4.xml      | test4.xml
test5.xml       | *.xml          | test5.xml      | test5.xml
test6.abc       | *.xml          | test6.abc.xml  | test6.abc.xml
----------------+----------------+----------------+----------------
test7.xml       | *.txt          | test7.xml      | test7.xml.txt
test8.bmp       | *.txt          | test8.bmp      | test8.bmp.txt
test9.bmp       | *.xml          | test9.bmp      | test9.bmp.xml     

对于上表的最后三行,我希望像未知的abc扩展名一样使用双扩展名.像Microsoft Word这样的应用程序的行为是这样的(如果Save as type与用户在File name中给定的扩展名不匹配,它们总是添加双扩展名.)

For the last three lines of the above table I would expect a double extension like it does for the unknown abc extension. Applications like Microsoft Word behave like that (they always add the double extension if the Save as type doesn't match the extension given by the user in File name).

有办法改变吗?

在对话框关闭后我不想这样做,因为那我必须再次检查文件是否已经存在以及文件名是否太长.

I don't want to do it after the dialog is closed because then I've to check again if the file already exists and if the file name is not too long.

更新:

我已经使用Ubuntu 18.04在M​​ONO框架上进行了测试.在这种情况下,永远不会创建双扩展名,例如:使用MONO的test3.abc与使用.NET Framework 4.5(Windows 10)的test3.abc.txt.

I've tested it as well with the MONO framework using Ubuntu 18.04. In that case a double extension is never created, e.g.: test3.abc using MONO vs test3.abc.txt using .NET Framework 4.5 (Windows 10).

推荐答案

我的Github(batressc)源代码

简单来说,除*.abc以外的所有扩展名在Windows OS中都是有效的文件类型扩展名.在true中设置AddExtension属性时,仅当您放置未注册的文件扩展名时,.NET Framework才会在保存文件对话框中自动自动完成具有所选文件扩展名的文件名.

In simple terms, all extensions except *.abc are valid file type extension in Windows OS. When you set AddExtension property in true, only if you put a unregistered file extension, .NET Framework autocomplete automatically the file name with value of selected file extension in the save file dialog.

在此示例中:

  1. 在Windows 10操作系统中,我没有注册文件扩展名*.abc(我们可以使用regedit.exeHKEY_CLASSES_ROOT下查看文件类型扩展名)
  1. In my Windows 10 OS, I don't have registered the file type extension *.abc (We can view file type extensions under HKEY_CLASSES_ROOT using regedit.exe)

  1. 我以预期的结果测试"test3.abc"案例

  1. 我在HKEY_CLASSES_ROOT中注册了*.abc文件类型扩展名,只是创建了一个名称为.abc
  2. 的新密钥.
  1. I register the *.abc file type extension in HKEY_CLASSES_ROOT only creating a new key with name .abc

  1. 我重复第2点,现在txt部分不可见
  1. I repeat point 2 and now the txt part is not visible

要解决此问题,我们可以创建一个扩展方法,他可以确保在保存文件对话框中添加选定的扩展名.

To fix this, we can create an extension method that he makes sure to add the selected extension in the save file dialog

// It's good practice create extensions methods in the same namespace of the class to extend
namespace System.Windows.Forms {
    public static class SaveFileDialogFileTypeExtension {
        // Retrieving only text of the file extensions
        private static List<string> GetFileExtensions(string filter) {
            List<string> extensions = new List<string>();
            var filtersRaw = filter.Split('|');
            for (int i = 0; i < filtersRaw.Length; i++) {
                if (i % 2 != 0) {
                    // Supporting multi doted extensions
                    extensions.Add(filtersRaw[i].Trim().Replace("*", "").Substring(1));
                }
            }
            return extensions;
        }

        // Getting filename with selected extension
        public static string FileNameForceExtension(this SaveFileDialog dialog) {
            string fileName = dialog.FileName;
            // Retrieving the current selected filter index
            List<string> extensions = GetFileExtensions(dialog.Filter);
            string selectedExtension = extensions[dialog.FilterIndex - 1];
            // Adding extension if need it
            if (!fileName.EndsWith($".{selectedExtension}")) {
                fileName = $"{fileName}.{selectedExtension}";
            }
            return fileName;
        }
    }
}

我们可以使用FileNameForceExtension代替使用FileName.就我而言,我使用以下形式:

Instead to use FileName we can use FileNameForceExtension. In my case, I use it that form:

textBoxFileName.Text = dialog.FileName + " | " + dialog.FileNameForceExtension();

这是使用test7.xml*.txt文件扩展名的结果:

And this is the result using test7.xml with *.txt file extension:

注释

在Windows窗体FileDialog的实现中( FileDialog.cs )未指定代码,无法使用OS函数或方法查找文件扩展名,GetExtensionHasExtension方法仅验证模式.<extension>在文件名的最后(路径. GitHub上的cs ).也许Windows OS中注册扩展的验证是Framework的一项内部功能,而这对于开发人员来说是不可见的...:(

In the implementation of FileDialog of Windows Forms (FileDialog.cs on GitHub) inside the code not specified to find the file extensions using OS functions or methods, GetExtension and HasExtension methods only validate the pattern .<extension> at last of the file name (Path.cs on GitHub). Maybe the validation of the registered extensions in the Windows OS is an internal functionality of the Framework and this is not visible for the developer... :(

这篇关于SaveFileDialog AddExtension无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆