当前位置:首页 > .NET其他

新路径选择对话框Vista-Style FolderBrowserDialg

发表于 2017-06-19 23:10

以前一直觉得.net提供的FolderBrowserDialog很难用,不仅选起来麻烦,而且连输入路径的文本框也没有。如图:

FolderBrowserDialog.PNG

后来发现Visual Studio新建项目时的选择路径对话框很好用,和选择文件时几乎时一样的,不仅左边可以选择磁盘,顶部和底部也有文本框可以直接输入路径,非常方便。如图:

FolderBrowserDialog_VisualStudio.PNG

于是马上百度,苦苦查找无果。


又过了许久,我实在无法忍受了,准备自己动手写一个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);
}

 

效果如图:

FolderBrowserDialog_VistaStyle.PNG

以下为源码

FolderBrowserDialog20170619