这几天在重温C#.Net-WPF,拿个以前废弃的项目练练手,其中遇到一个问题:
WPF自身的命名空间System.Windows中没有打开文件夹的对话框,只有OpenFileDialog可以打开文件。
网上搜了很多帖子,无外乎三种答案
- 使用以前WinForm的FolderBrowserDialog:为了避免命名空间冲突导致的代码繁琐(两边都有OpenFileDialog)以及出于一些洁癖的原因,我这次决定坚决不使用WinForm,反正自己做项目也没工期什么的,大不了不做了~
- 扩写System.Windows.OpenFileDialog:要么自己扩写,要么用一些别人写好的开源组件,一个是太麻烦,另一个心里总觉得不太舒服
- 使用微软官方的扩展包Microsoft.WindowsAPICodePack:这个看起来很不错,但是也有缺点,就是完全要求Windows版本>=6.0,而公司的电脑还是杯具的5.1,只能放弃
正在纠结之际,国外著名社区 Stack Overflow 上看到这么一篇帖子:
一位大佬想出了一个看起来很orz的方法,不过反正也没其他解决方案,姑且一试。
这位大佬将Filter设置成一个非常非常长的扩展名从而起到隐藏所有文件的目的:
openFileDialog1.Filter = "folders|*.neverseenthisfile"
然后把文件名设为一个”r”换行符来骗过OpenFileDialog,这样只要不改动文件名就能直接按打开按钮。当然同时还需要把CheckFileExists给false掉……
我修改了他的原型代码后得到了如下版本:
OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "folders|*.sado;fjsdal;fj"; ofd.FileName = "r"; ofd.CheckFileExists = false; ofd.CheckPathExists = true; ofd.ValidateNames = false; if (ofd.ShowDialog() == true) { ofd.FileName = ofd.FileName.TrimEnd('r'); int lastSeparatorIndex = ofd.FileName.LastIndexOf('\'); ofd.FileName = ofd.FileName.Remove(lastSeparatorIndex); txtCOutputPath.Text = ofd.FileName; }
运行后成功取到了目录,并且哪怕不当心在文件文本框里输入了内容也可以正常工作了。本以为事情到此为止,我甚至都把这篇博文发表了出来(第一稿是到这行的前一个句号就结束的),到家后再试才发现家里的娜娜不买账!!!
仔细研究后,发现貌似娜娜不认ValidateNames属性,不论这个值是true还是false,她一定会检查文件名是否合法……好在她并不在意文件是否真的存在,所以代码稍加修改还是可以用:
OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = CoffeeScript._ofdOutputFilter; ofd.FileName = "Filename will be ignored"; ofd.CheckFileExists = false; ofd.CheckPathExists = true; //ofd.ValidateNames = false; if (ofd.ShowDialog() == true) { //ofd.FileName = ofd.FileName.TrimEnd('r'); int lastSeparatorIndex = ofd.FileName.LastIndexOf('\'); ofd.FileName = ofd.FileName.Remove(lastSeparatorIndex); txtCOutputPath.Text = ofd.FileName; return true; } return false;
不过这种做法还是有一定问题的,如果用户不当心选中了一个文件夹,那他后面的麻烦就大了……看来这个问题还需要再研究一下……
Apologies for no Chinese input on this computer.
Is there any way I can filter files with file names instead of using file extension?
Thanks
抱歉我还真没试过,手头也刚好没有VS,直觉告诉我直接把
*.extension
换成需要的完整文件名应该可以,但是没办法验证