以前一直觉得.net提供的FolderBrowserDialog很难用,不仅选起来麻烦,而且连输入路径的文本框也没有。如图:
后来发现Visual Studio新建项目时的选择路径对话框很好用,和选择文件时几乎时一样的,不仅左边可以选择磁盘,顶部和底部也有文本框可以直接输入路径,非常方便。如图:
于是马上百度,苦苦查找无果。
又过了许久,我实在无法忍受了,准备自己动手写一个FolderBrowserDialog,可能功能不是那么全,但是能满足基本需求,而且比.net framework自带的方便。
开始动手,新建一个类继承FolderBrowserDialog,怎么也生成不成功。仔细一看FolderBrowserDialog是一个sealed类,无法继承。然后下载了一下.net framework的源码大概看了下继承关系和实现方法,它是靠API函数SHBrowseForFolder显示的对话框。想想自己动手做的话可能比较困难。为什么不再到网上找找呢。
于是我用的Bing,一搜索,果然不出我所料,很多人也有这个疑问,觉得Visual Studio的路径选择对话框好用但是不知道怎么实现的,经过一番查找后,原来Visual Studio是用的对话框叫Vista-Style folder browser dialog,其实它就是使用的OpenFileDialog,怪不得这两个看着这么像。
看了一下作者的实现方法,使用的是反射,很有趣。第一眼看到时给我的感觉是:竟然还有这样的操作!!!惊艳,以后可以学学这种方法。
var r = new Reflector("System.Windows.Forms"); uint num = 0; Type typeIFileDialog = r.GetType("FileDialogNative.IFileDialog"); object dialog = r.Call(ofd, "CreateVistaDialog"); r.Call(ofd, "OnBeforeVistaDialog", dialog); uint options = (uint)r.CallAs(typeof(System.Windows.Forms.FileDialog), ofd, "GetOptions"); options |= (uint)r.GetEnum("FileDialogNative.FOS", "FOS_PICKFOLDERS"); r.CallAs(typeIFileDialog, dialog, "SetOptions", options); object pfde = r.New("FileDialog.VistaDialogEvents", ofd); object[] parameters = new object[] { pfde, num }; r.CallAs2(typeIFileDialog, dialog, "Advise", parameters); num = (uint)parameters[1]; try { int num2 = (int)r.CallAs(typeIFileDialog, dialog, "Show", hWndOwner); flag = 0 == num2; } finally { r.CallAs(typeIFileDialog, dialog, "Unadvise", num); GC.KeepAlive(pfde); }
效果如图:
以下为源码