ShellMenuWindows 2008 R2Windows 2008Windows VistaFormsWindows 7Windows 2003Windows XPBeginnerWPFC# 4.0IntermediateDevWindows.NETC#
最近使用的 (MRU) 文件管理器组件






4.69/5 (6投票s)
一个 MRU 管理器组件,可以放置在 Windows Form 或 WPF 窗口上,并与菜单、MenuStrip、应用程序设置、注册表和 Windows 最近使用的文件集成。
引言
我有一个小型项目需要一个 MRU。我喜欢较新应用程序通过 SHAddToRecentDocs
系统函数集成到 Windows,并在任务栏的跳转列表中显示 MRU 文件的方式。我希望在信息持久化方面具有灵活性,至少能够使用注册表或将其值存储在应用程序的本地设置文件中。我还希望它能与 Windows Forms 或 WPF 配合使用。此类实现了所有这些功能。
背景
网上有很多关于 .NET 项目 MRU 解决方案的优秀示例。我对这个组件借鉴了以下两个:
- 为 Windows 应用程序添加最近使用的文件 (MRU) 列表,作者:Adib Saad
- 将文件添加到 Windows MRU/最近使用的文档列表,作者:Rick Strahl
我想集两者的优点,并能直接将其拖放到窗体上。因此,就诞生了这里提供的代码。
Using the Code
此类既可以作为组件直接拖放到窗体上,也可以作为应用程序中的本地实例使用。为了演示代码的工作方式,我将重点介绍前者,并描述它与本地实例的关系。
- 将 MRUManager.cs 文件添加到您的项目中并重新生成项目。对于 Window Forms 项目,这应该会将
MRUManager
和MenuStripMRUManager
组件添加到工具箱中。 - 所有 MRU 类默认使用应用程序设置来存储历史记录。为了使用此功能,您必须为项目配置设置。实际上,您需要确保您的项目有一个派生自
System.Configuration.ApplicationSettingsBase
的类,并且您至少配置了一个设置。MRUManager
会在程序集中查找此类,并获取它找到的第一个类来存储 MRU 文件历史记录。该类将使用 "__MRUList__
" 作为存储文件历史记录的属性名称。如果没有定义设置实例,则会抛出异常。 - 或者,您也可以将存储功能更改为注册表。要做到这一点,您必须手动创建
MRUManager
(或其派生类)实例,并将RegisterFileListStorage
实例作为最后一个参数传递给构造函数。这将查找执行程序集中的公司和产品名称(如果找不到则使用程序集名称),并将 MRU 列表存储在 HKEY_CURRENTUSER\Software\[[Company]\[Product]|AsmName]\MRU 中。请参阅本节末尾的示例代码。 - 如果您只需要 MRU 功能,并且负责所有与 UI 的交互,那么您可以简单地使用
MRUManager
。您可以将其拖放到窗体上,或在主窗体中创建一个实例。它仅提供与设置或注册表以及 Windows 的交互来维护文件列表。如果您希望该类还能在 WinForms 中显示菜单项列表,请将MenuStripMRUManager
拖放到窗体上。理想情况下,此窗体应该是包含用于处理文件操作(打开、保存等)的MenuStrip
的窗体。如果您想将其用于 WPF 项目,请在包含Menu
实例的主窗口中创建MenuMRUManager
的实例。 - 重要提示:如果您想从 Windows 的“最近使用的项目”列表中提取项目,则必须将有效扩展名列表提供给
MRUManager
实例的FileExtensions
属性。此列表必须是竖线分隔的扩展名列表,不带句点(例如:“doc|docx|html|rtf
”)。 - 重要提示 (2):应用程序必须报告所有文件打开情况才能维护列表。为此,应用程序必须在每次打开新文件时调用
MRUManager
实例的AddRecentFile
方法。 - 如果您希望维护的最近文件列表数量多于或少于 10 个,请更改
MaxHistoryCount
属性。 - 如果您想自动创建一个最近使用的文件菜单列表
- 在窗体的
MenuStrip
(或 WPF 窗口中的Menu
)中创建一个ToolStripMenuItem
,它将作为下拉菜单项承载该菜单列表。 - 将此菜单项分配给
MRUManager
派生实例的RecentFileMenuItem
属性。 - 通过访问
MRUManager
实例的事件,双击RecentFileMenuItemClick
事件,创建一个用户单击最近文件菜单项时执行的操作。完成方法体中您想要执行的操作。通常,这是打开文件。 - 默认情况下,最近使用的文件列表末尾会有一个菜单项用于清除所有 MRU 条目。默认情况下,其标题为“
Clear List
”。这可以通过更改MRUManager
实例的ClearListMenuItemText
属性来更改。如果您想删除此菜单项,请将属性值设置为空。private void mruManager_RecentFileMenuItemClick(string file) { OpenFile(file); }
- 如果除了清除列表之外,您在 MRU 列表被清除时需要执行其他操作,请为
MRUManager
实例的ClearListMenuItemClick
事件创建一个操作方法。private void mruManager_ClearListMenuItemClick(StringCollection files) { foreach (string file in files) ProcessClearedFile(file); }
- 在窗体的
如果您想手动完成所有这些操作,上面提到的所有属性都是 MRUManager
类中的 public
成员。其中大部分可以在单个构造函数调用中完成。
var mgr = new MenuStripMRUManager("doc|docx|html|rtf", /* FileExtensions */
recentFileToolStripMenuItem, /* RecentFileMenuItem */
mruManager_RecentFileMenuItemClick, /* RecentFileMenuItemClick */
mruManager_ClearListMenuItemClick, /* ClearListMenuItemClick */
new RegistryFileListStorage() /* Storage (see below for explanation) */
);
mgr.ClearListMenuItemText = "Clear my list now";
mgr.MaxHistoryCount = 20;
构造函数的最后一个参数需要一些解释。指定的类(RegistryFileListStorage
)会将历史记录的存储位置从应用程序设置切换到注册表(参见上面的 #2 和 #3)。
如果您想使用拖放式 WinForms 组件同时使用注册表,可以将 StorageHandler
属性设置为相同的类实例。这也可以让您按需更改注册表项。
// In constructor for main Form
InitializeComponent();
mruManager1.StorageHandler = new Community.Core.MRUManager.RegistryFileListStorage()
{ SubKeyName = "MyRegistryLoc\\MRU" };
历史
- 2018 年 3 月 18 日:使用 ReSharper 重新格式化代码,并加入了用户的修复。
- 2015 年 8 月 21 日:首次发布。
- 2015 年 8 月 25 日:将菜单和存储处理提取到接口类中,并支持 WPF 和 WinForm 解决方案。修复了 Bug。添加了文档。