SaveFileDialog AddExtension无法按预期工作
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SaveFileDialog AddExtension无法按预期工作相关的知识,希望对你有一定的参考价值。
我有以下C#代码,它使用SaveFileDialog并将AddExtension属性设置为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
的以下组合。
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
中给出的扩展名不匹配,它们总是添加双扩展名)。
有办法改变吗?
关闭对话框后我不想这样做,因为我要再次检查文件是否已经存在以及文件名是否太长。
更新:
我使用Ubuntu 18.04对MONO框架进行了测试。在这种情况下,永远不会创建双扩展,例如:使用.NET Framework 4.5(Windows 10)使用MONO vs test3.abc
的test3.abc.txt
。
Source code on my Github (batressc)
简单来说,除了*.abc
之外的所有扩展都是Windows操作系统中的有效文件类型扩展。在AddExtension
中设置true
属性时,仅当您放置未注册的文件扩展名时,.NET Framework才会自动在保存文件对话框中使用所选文件扩展名的值自动填充文件名。
在这个例子中:
- 在我的Windows 10操作系统中,我没有注册文件类型扩展名
*.abc
(我们可以使用HKEY_CLASSES_ROOT
在regedit.exe
下查看文件类型扩展名)
- 我用预期的结果测试“test3.abc”情况
- 我在
*.abc
中注册HKEY_CLASSES_ROOT
文件类型扩展名,只创建一个名为.abc
的新密钥
- 我重复第2点,现在
txt
部分不可见
要解决此问题,我们可以创建一个扩展方法,确保在保存文件对话框中添加所选扩展名
// 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;
}
}
}
而不是使用FileName
我们可以使用FileNameForceExtension
。在我的情况下,我使用它形式:
textBoxFileName.Text = dialog.FileName + " | " + dialog.FileNameForceExtension();
这个结果使用test7.xml
和*.txt
文件扩展名:
笔记
在未指定使用OS函数或方法查找文件扩展名的代码中的Windows窗体(FileDialog
)的FileDialog.cs on GitHub的实现中,GetExtension
和HasExtension
方法仅在文件名的最后验证模式.<extension>
(Path.cs on GitHub)。也许在Windows操作系统中注册的扩展的验证是框架的内部功能,这对于开发人员来说是不可见的...... :(
以上是关于SaveFileDialog AddExtension无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章