FilterBuilder






4.55/5 (13投票s)
FilterBuilder 是一个简单的实用程序,允许您轻松创建对话框过滤器。

目录
引言
FilterBuilder
是一个简单的实用工具,可让您轻松创建对话框过滤器。它不仅包含 135 种最常见的文件过滤器,而且 FilterBuilder
还允许您创建无限组合的文件过滤器,而无需维护冗长的过滤器 string
。
背景
我编写 FilterBuilder
是因为我不喜欢为我使用的每个打开/保存对话框编写冗长的过滤器 string
。我需要一种快速、简单的方法来将过滤器添加到标准的打开和保存文件对话框中。
我的一些要求是:
- 该实用工具必须具有许多预设过滤器。
- 该实用工具还必须接受自定义过滤器。
- 该实用工具必须能够轻松添加/删除过滤器。
- 该实用工具必须能够生成完整的过滤器
string
。
Using the Code
要使用代码,请首先引用 FB.dll 库。它位于 Bin/Release 文件夹中。
添加一个 Imports
语句,如下所示:
Imports FB
创建 FilterBuilder
类的实例。要添加过滤器,请调用实例的 Add
方法,并传入 FilterBuilder.Filters enum
中的值或自定义过滤器,如下所示:
'Add a text files filter
FilterBuild.Add(FilterBuilder.Filters.TextFiles)
'Add a custom filter
FilterBuild.Add("Foo Files", "foo")
要删除过滤器,请调用 Remove
方法。
'Remove rich text files filter
FilterBuild.Remove(FilterBuilder.Filters.RichTextFiles)
要获取完整的过滤器 string
,请调用 ToString
方法。
'Get filter string
OpenFileDialog1.Filter = FilterBuild.ToString()
工作原理
编写对话框过滤器的标准方法如下:
"Plain Text Files (*.txt)|*.txt"
而在 FilterBuilder
中,可以使用这种方式实现相同的功能:
FilterBuild.Add(FilterBuilder.Filters.TextFiles)
毫无疑问,第二个示例使用起来要容易得多,并且在不同的对话框之间也建立了一致性。
FilterBuilder
使用 List(Of String)
和 StringBuilder
来跟踪过滤器,并返回完整的过滤器 string
。
为了简单起见,我选择不让 FilterBuilder
直接继承自 List(Of T)
,而是将其用作内部组件。我认为 List(Of T)
暴露了许多 FilterBuilder
实际需要的功能和属性。
通过 Add
方法添加的所有过滤器都会添加到内部 List
中,反之,通过 Remove
方法删除的过滤器也会从 List
中移除。
就是一个普通的列表。简单吧?
如果将 enum
值传递给 Add
方法(有关更多信息,请参阅“示例”部分),则该值将通过 private ReturnFilterAsString
方法转换为 string
值,然后添加到 List
中。如果传入两个 string
值,则过滤器 string
将在关联的 Add
方法中构建,并添加到 List
中。
最棒的部分实际上是获取所需的过滤器 string
- 用于打开和保存文件对话框。如“使用代码”部分所述,这是通过 ToString
方法完成的。ToString
方法使用 For Each
循环迭代 List(Of String)
中的所有当前项,并将每个项与“|
”字符连接起来。之后,结果 string
将从两端修剪掉空格(“ ”)和“|
”字符。最终结果是一个已准备好在对话框中使用的过滤器 string
!
FilterGroups
到底什么是 FilterGroup
?嗯,我不知道是否有关于如下内容的官方术语:
"Documents (*.html,*.rtf,*.txt)|*.html;*.rtf;*.txt"
……所以,我创造了“FilterGroup
”这个术语。
正如您在上面看到的,这是一个多项过滤器 string
,允许显示 HTML、RTF 和 TXT 文件。但是,使用 FilterBuilder
,您不应该期望手动编写冗长的过滤器 string
。
这是实现上面示例相同结果的新方法:
Dim docsGroup As New FilterGroup("Documents")
'Add the filters in this group
With docsGroup
.Add(FilterBuilder.Filters.HTML_Files)
.Add(FilterBuilder.Filters.RichTextFiles)
.Add(FilterBuilder.Filters.TextFiles)
End With
好的,让我解释一下发生了什么。
- 第一行是创建一个
FilterGroup
类的新实例(它接受一个参数 - 组的名称)。 - “
.Add
”语句正在向组添加过滤器。Add
语句与FilterBuilder
类中的语句相同,因此您可以传入在使用FilterBuilder
正常使用时相同的过滤器。
那么,这与 FilterBuilder
本身有什么关系呢?
FilterBuilder
包含一个额外的 Add
方法,它只接受一个 FilterGroup
作为参数。所以,这意味着在完成创建 FilterGroup
后,您可以像这样将其传递给 FilterBuilder
:
FilterBuild.Add(docsGroup)
摘要
- 创建一个
FilterGroup
,其名称将显示在“打开/保存”对话框中(例如,“Documents”)。 - 使用组的
Add
方法,添加将包含在此组中的过滤器。 - 使用您的
FilterBuilder
实例的Add
方法将FilterGroup
添加到主过滤器列表中。 - 像往常一样调用
ToString
方法以获取最终的过滤器string
。
注意:有关更高级的示例,请查看演示项目下载中的示例 #6。
系统文件类型
如果您还没有被我刚才读到的内容说服,那么我向您保证,这一定会引起您的注意。
系统文件类型 - 只需知道扩展名即可添加对话框过滤器的功能。没有描述,没有研究,只有一个简单的文件扩展名。所以,这个
"dll"
变成了这个
"Application Extensions (*.dll)|*.dll"
问题:好的,那么这个小小的扩展名是如何变成一个完整的内部过滤器字符串的?
FilterBuilder
从计算机的注册表中获取正确的描述。对于这一步,我使用了与 Man Vuong 的文章 此处 [^] 中概述的完全相同的方法,我建议您阅读一下。- 获取描述后,
FilterBuilder
会将其与扩展名连接起来,并添加“*”、“.”和“|”字符。
问题:我如何通过知道其扩展名来添加过滤器?
'Add the filter
FilterBuild.Add("dll")
与通常添加过滤器的方式几乎相同。只是将 string
扩展名传递给 Add
方法。
注意:您可以选择在扩展名前加上点(例如,“.dll”,而不是“dll”)。两种方式都可以。
问题:Add
方法的可选复数参数呢?
'Add the filter (first way)
FilterBuild.Add("dll")
'Add the filter (second way)
FilterBuild.Add("dll", False)
当我第一次创建 Filters enum
时,我将描述设置为复数形式,以考虑可以选择多个文件。因此,默认情况下,当从注册表中检索系统文件描述时,会对其进行检查和修改,以确保它们是复数形式(即,“Files”而不是“File”)。如果您不希望这些描述是复数形式,则将“False
”值作为此重载 Add
方法的第二个参数传递(如上所示)。
附加信息
您可以通过调用 GetSystemFileTypes()
方法来获取所有系统文件类型扩展名的列表。
Dim l As List(Of String) = FilterBuild.GetSystemFileTypes()
结论
当您不知道扩展名的描述,或者希望在注册表中的值更改时自动更新时,系统文件类型非常有用。
摘要
就是这样!
只需调用 Add
方法 - 传入文件的 string
扩展名。如果该文件存在于用户的系统中,它将被添加到过滤器字符串中。
系统文件类型图标
作为上述主题的延续,本节将介绍 FilterBuilder
如何支持获取计算机注册表中任何文件类型的系统文件类型图标。
下面是一个获取预设过滤器(来自 FilterBuilder.Filters enum
的一个)文件类型图标的示例:
Dim icon As System.Drawing.Icon = _
FilterBuild.GetSystemFileTypeIcon( _
FilterBuilder.Filters.RichTextFiles)
现在是一个获取系统文件类型(非 enum
中的)文件类型图标的示例:
Dim icon As System.Drawing.Icon = _
FilterBuild.GetSystemFileTypeIcon("rtf")
注意:文件类型图标返回的是(不出所料地)Icon 格式,但可以像下面的完整示例那样更改为位图。
完整示例
'Declarations
Dim FilterBuild As New FilterBuilder()
Dim picIconView As New System.Windows.Forms.PictureBox()
'Get the icon for XML files
Dim icon As System.Drawing.Icon = _
FilterBuild.GetSystemFileTypeIcon( _
FilterBuilder.Filters.XML_Files)
'Convert icon to bitmap and set as image
picIconView.Image = icon.ToBitmap()
附加信息
要更改返回图标的大小,您可以修改 FileTypeIconSize 属性
。它是一个 16x16 像素或 32x32 像素的图标。
摘要
就是这样!
要获取文件类型的关联系统图像,只需调用 GetSystemFileTypeIcon
方法 - 传入预设过滤器(来自 Filters enum
)或文件类型的 string
扩展名。
自定义过滤器
FilterBuilder
的一个很棒的功能是,它不仅允许您使用预设过滤器的任何组合,还允许您包含自定义过滤器。这特别有用,如果您像我一样,在您的应用程序中使用自己的文件类型。继续阅读,了解如何在只有一行代码的情况下添加自定义过滤器……
到目前为止,您可能已经理解了,过滤器是通过重载的 Add
方法添加的。其中一个 Add
方法接受两个 String
参数。让我们以下面的示例为例:
FilterBuild.Add("Foo Files", "foo")
在此示例中,我添加了一个自定义过滤器,它只允许扩展名为 .foo 的文件显示。这与 string
"Foo Files (*.foo)|*.foo"
注意:您可以选择在扩展名前加上点(例如,“.foo”,而不是“foo”)。两种方式都可以。
摘要
就是这样!
要添加自定义过滤器,只需调用 Add
方法 - 传入文件的描述和文件的扩展名。
示例
以下是一些展示 FilterBuilder
中可用方法的示例。更多示例包含在附加的“演示项目”下载中。
注意:如果需要,您可以创建一个 Filters
数组,然后只需将数组传递给重载的 Add
方法。这在第二个示例中显示。
示例 #1 -- 文本、RTF 和 HTML 文件过滤器
'Declarations
Dim FilterBuild As New FilterBuilder()
Dim ofd As New OpenFileDialog()
'Add the filters
FilterBuild.Add(FilterBuilder.Filters.TextFiles)
FilterBuild.Add(FilterBuilder.Filters.RichTextFiles)
FilterBuild.Add(FilterBuilder.Filters.HTML_Files)
With ofd
'Set the filter
.Filter = FilterBuild.ToString()
'Set filter index to the first item
.FilterIndex = 1
'Get the file extension of text files
.DefaultExt = FilterBuild.GetFileExtension( _
FilterBuilder.Filters.TextFiles)
.ShowDialog()
End With
正如您在上例中可能注意到的,我使用了 GetFileExtension
方法 - 它返回 FilterBuilder.Filters enum
的任何预设值的关联文件扩展名(在本例中为“.txt”)。
示例 #2 -- 许多常见音乐文件过滤器
'Declarations
Dim FilterBuild As New FilterBuilder()
Dim ofd As New OpenFileDialog()
'Make an array of filters
Dim filters() As FilterBuilder.Filters = { _
FilterBuilder.Filters.MP3_AudioFiles, _
FilterBuilder.Filters.AAC_Files, _
FilterBuilder.Filters.WAVE_AudioFiles, _
FilterBuilder.Filters.MPEG2_AudioFiles, _
FilterBuilder.Filters.RealAudioFiles, _
FilterBuilder.Filters.MIDI_Files}
'Add the "filters" array - the add method is overloaded
FilterBuild.Add(filters)
With ofd
'Set the filter
.Filter = FilterBuild.ToString()
'Sets the selected item in the filter box to MP3 files
.FilterIndex = FilterBuild.GetFilterIndex( _
FilterBuilder.Filters.MP3_AudioFiles)
'Set the default extension
.DefaultExt = ".mp3"
.ShowDialog()
End With
您可以使用 GetFilterIndex
方法(如上所示)来获取相关的 FilterIndex
,您可以将其分配给 OpenFileDialog
/SaveFileDialog
的 FilterIndex
属性。
示例 #3 -- 自定义和系统过滤器
'Declarations
Dim FilterBuild As New FilterBuilder()
Dim ofd As New OpenFileDialog()
'Add the Custom filters
FilterBuild.Add("Foo Files", "foo")
FilterBuild.Add("Custom Files", "custm")
FilterBuild.Add("My Random Files", "rndm")
'System File Types
FilterBuild.Add("xml")
FilterBuild.Add("dll")
FilterBuild.Add("bat")
With ofd
'Set the filter
.Filter = FilterBuild.ToString()
'Sets the filter index to the first item
.FilterIndex = 1
'Set the default extension
.DefaultExt = ".foo"
.ShowDialog()
End With
在上面的最后一个示例中,我正在添加六个文件类型,前三个是自定义的(由程序员创建),最后三个是从注册表中获取的已知文件类型。有关更多信息,请参阅本文前面的“自定义过滤器”和“系统文件类型”部分。
关注点
在编写重载的 Add
方法时,我遇到了一些特别奇怪的事情。最初,我写了两个 Add
方法来接受 FilterBuilder.Filters enum
的 ParamArray
值以便于使用,但在 IDE 中测试 Add
方法时,我发现输入“.Add(
”后,enum
值没有显示 Intellisense。也许 Intellisense 不会与 ParamArrays
一起显示?
我通过修改两个 Add
方法来接受 FilterBuilder.Filters
类型的 Arrays
(而不是 ParamArrays
)来解决了这个问题。请参阅上面的“示例”部分。
致谢
感谢 Man Vuong 和他的文章 C# 中获取注册文件类型及其关联图标 [^]。我修改了他的一些源代码并将其转换为 VB.NET,以提供系统文件类型支持。
历史
2009 年 10 月 25 日 - 版本 1.25
- 在
FilterBuilder.Filters enum
中添加了“WindowsIcons”和“EXIF_ImageFiles”过滤器。 - 添加了
GetFileDescription()
方法。 - 添加了
ReadOnly Count()
属性。 - 添加了
GetFileDescription()
、GetFileExtension()
和GetFilterIndex()
方法的新重载,它们只接受过滤器字符串作为参数。
支持系统文件类型
- 添加了
GetSystemFileTypeDescription()
方法。 - 添加了
GetSystemFileTypeIcon()
方法。 - 添加了
GetSystemFileTypeInfo()
方法。 - 添加了
GetSystemFileTypes()
方法。 - 修改了
FilterGroup class
以支持新的系统文件类型(请参阅本文前面的“系统文件类型”部分)。 - 在
FilterBuilder
和FilterGroup
类中添加了“Add
”方法的新重载,它只接受一个string
参数(扩展名),并从用户的计算机获取文件描述。 - 在
FilterBuilder class
中添加了“Contains
”和“Remove
”方法的新重载,以支持新的系统文件类型。 - 添加了
FileTypeIconSize()
属性。 - 添加了
ImageSize enum
。 - 修改了本文中的示例 #3,以包含系统文件类型示例。
- 在附加的演示下载中添加了示例 #7。此示例演示了与系统文件类型交互时使用的方法。
- 更改了演示下载的用户界面,以包含系统文件类型的交互式示例。立即下载新的演示版,查看更改!
2009 年 9 月 6 日 - 版本 1.10
- 在
FilterBuilder.Filters enum
中添加了“All Files”过滤器。 - 更改了
Add
方法的string
重载。它最初接受一个string
参数(自定义过滤器string
),但感谢 Kschuler 的建议,它现在接受两个string
参数,即文件类型的描述和扩展名。请参阅本文前面的“自定义过滤器”部分。 - 添加了
FilterGroup
类,并修改了源代码以适应新的FilterGroups
。请参阅本文前面的“FilterGroups
”部分。 - 从下载文件中删除了“obj”文件夹。感谢 pimb2 提供此提示。
2009 年 9 月 - 版本 1.00