65.9K
CodeProject 正在变化。 阅读更多。
Home

最近使用的 (MRU) 文件管理器组件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.69/5 (6投票s)

2015年8月21日

CPOL

5分钟阅读

viewsIcon

27443

downloadIcon

576

一个 MRU 管理器组件,可以放置在 Windows Form 或 WPF 窗口上,并与菜单、MenuStrip、应用程序设置、注册表和 Windows 最近使用的文件集成。

引言

我有一个小型项目需要一个 MRU。我喜欢较新应用程序通过 SHAddToRecentDocs 系统函数集成到 Windows,并在任务栏的跳转列表中显示 MRU 文件的方式。我希望在信息持久化方面具有灵活性,至少能够使用注册表或将其值存储在应用程序的本地设置文件中。我还希望它能与 Windows Forms 或 WPF 配合使用。此类实现了所有这些功能。

背景

网上有很多关于 .NET 项目 MRU 解决方案的优秀示例。我对这个组件借鉴了以下两个:

我想集两者的优点,并能直接将其拖放到窗体上。因此,就诞生了这里提供的代码。

Using the Code

此类既可以作为组件直接拖放到窗体上,也可以作为应用程序中的本地实例使用。为了演示代码的工作方式,我将重点介绍前者,并描述它与本地实例的关系。

  1. MRUManager.cs 文件添加到您的项目中并重新生成项目。对于 Window Forms 项目,这应该会将 MRUManagerMenuStripMRUManager 组件添加到工具箱中。
  2. 所有 MRU 类默认使用应用程序设置来存储历史记录。为了使用此功能,您必须为项目配置设置。实际上,您需要确保您的项目有一个派生自 System.Configuration.ApplicationSettingsBase 的类,并且您至少配置了一个设置。MRUManager 会在程序集中查找此类,并获取它找到的第一个类来存储 MRU 文件历史记录。该类将使用 "__MRUList__" 作为存储文件历史记录的属性名称。如果没有定义设置实例,则会抛出异常。
  3. 或者,您也可以将存储功能更改为注册表。要做到这一点,您必须手动创建 MRUManager(或其派生类)实例,并将 RegisterFileListStorage 实例作为最后一个参数传递给构造函数。这将查找执行程序集中的公司和产品名称(如果找不到则使用程序集名称),并将 MRU 列表存储在 HKEY_CURRENTUSER\Software\[[Company]\[Product]|AsmName]\MRU 中。请参阅本节末尾的示例代码。
  4. 如果您只需要 MRU 功能,并且负责所有与 UI 的交互,那么您可以简单地使用 MRUManager。您可以将其拖放到窗体上,或在主窗体中创建一个实例。它仅提供与设置或注册表以及 Windows 的交互来维护文件列表。如果您希望该类还能在 WinForms 中显示菜单项列表,请将 MenuStripMRUManager 拖放到窗体上。理想情况下,此窗体应该是包含用于处理文件操作(打开、保存等)的 MenuStrip 的窗体。如果您想将其用于 WPF 项目,请在包含 Menu 实例的主窗口中创建 MenuMRUManager 的实例。
  5. 重要提示:如果您想从 Windows 的“最近使用的项目”列表中提取项目,则必须将有效扩展名列表提供给 MRUManager 实例的 FileExtensions 属性。此列表必须是竖线分隔的扩展名列表,不带句点(例如:“doc|docx|html|rtf”)。
  6. 重要提示 (2):应用程序必须报告所有文件打开情况才能维护列表。为此,应用程序必须在每次打开新文件时调用 MRUManager 实例的 AddRecentFile 方法。
  7. 如果您希望维护的最近文件列表数量多于或少于 10 个,请更改 MaxHistoryCount 属性。
  8. 如果您想自动创建一个最近使用的文件菜单列表
    1. 在窗体的 MenuStrip(或 WPF 窗口中的 Menu)中创建一个 ToolStripMenuItem,它将作为下拉菜单项承载该菜单列表。

    2. 将此菜单项分配给 MRUManager 派生实例的 RecentFileMenuItem 属性。
    3. 通过访问 MRUManager 实例的事件,双击 RecentFileMenuItemClick 事件,创建一个用户单击最近文件菜单项时执行的操作。完成方法体中您想要执行的操作。通常,这是打开文件。
    4. 默认情况下,最近使用的文件列表末尾会有一个菜单项用于清除所有 MRU 条目。默认情况下,其标题为“Clear List”。这可以通过更改 MRUManager 实例的 ClearListMenuItemText 属性来更改。如果您想删除此菜单项,请将属性值设置为空。
      private void mruManager_RecentFileMenuItemClick(string file)
      {
         OpenFile(file);
      }
    5. 如果除了清除列表之外,您在 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。添加了文档。
© . All rights reserved.