SaveFileDialog AddExtension无法正常工作 [英] SaveFileDialog AddExtension doesn't work as expected
问题描述
我有以下C#代码,该代码正在使用 AddExtension 属性添加到true
:
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 name
和Save 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在MONO框架上进行了测试.在这种情况下,永远不会创建双扩展名,例如:使用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).
推荐答案
简单来说,除*.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.
在此示例中:
- 在Windows 10操作系统中,我没有注册文件扩展名
*.abc
(我们可以使用regedit.exe
在HKEY_CLASSES_ROOT
下查看文件类型扩展名)
- In my Windows 10 OS, I don't have registered the file type extension
*.abc
(We can view file type extensions underHKEY_CLASSES_ROOT
usingregedit.exe
)
- 我以预期的结果测试"test3.abc"案例
- 我在
HKEY_CLASSES_ROOT
中注册了*.abc
文件类型扩展名,只是创建了一个名称为.abc
的新密钥.
- I register the
*.abc
file type extension inHKEY_CLASSES_ROOT
only creating a new key with name.abc
- 我重复第2点,现在
txt
部分不可见
- 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函数或方法查找文件扩展名,GetExtension
和HasExtension
方法仅验证模式.<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屋!