最近文件管理器MRUManager的实现与使用

在日常使用电脑的过程中,经常需要重复打开相同的文件。为了避免每次都要浏览并重新打开相同的文件,设计了一个名为MRUManager的类,以简化这一过程。

MRUManager使用Windows注册表来存储最近打开的文件路径。如果对注册表不熟悉,可以查看Wikipedia的相关介绍,或者参考Microsoft的文档来了解C#类Microsoft.Win32.Registry的使用方法。

代码使用

可以立即使用MRUManager类,当然,需要自己承担风险。使用之前,需要满足一些基本要求。

在Visual Studio中,创建一个ToolStripMenuItem,作为最近文件列表的父菜单项。不要在这个菜单项中放置子菜单项,因为MRUManager会移除它们。

创建一个方法,其原型如下:

void myOwnRecentFileGotClicked_handler(object obj, EventArgs evt)

当用户点击最近文件列表中的一个项目时,这个方法将被调用。

创建MRUManager类的实例:

private MRUManager mruManager; private void Form1_Load(object sender, EventArgs e) { this.mruManager = new MRUManager( // 菜单项,将包含最近文件 this.recentFilesToolStripMenuItem, // 程序名称 "myProgram", // 当最近文件被点击时调用的函数 this.myOwn_recentFileGotClicked_handler, // 用户清除最近文件列表时调用的可选函数 this.myOwn_recentFilesGotCleared_handler); }

之后,可以调用两个公共方法:

public void AddRecentFile(string fileNameWithFullPath) public void RemoveRecentFile(string fileNameWithFullPath)

使用示例:

private void openToolStripMenuItem_Click(object obj, EventArgs evt) { FileDialog openFileDlg = new OpenFileDialog(); openFileDlg.InitialDirectory = Environment.CurrentDirectory; if (openFileDlg.ShowDialog() != DialogResult.OK) return; string openedFile = openFileDlg.FileName; // 现在将其交给MRUManager this.mruManager.AddRecentFile(openedFile); // 在这里处理文件 MessageBox.Show("通过'打开'菜单项,打开了: " + openedFile); }

如果用户打开(或保存)文件,当用户点击最近文件,但该文件不存在时,MRUManager会进行相应的处理。

类内部

以下是类的概览:

public class MRUManager { private string NameOfProgram; private string SubKeyName; private ToolStripMenuItem ParentMenuItem; private Action OnRecentFileClick; private Action OnClearRecentFilesClick; private void _onClearRecentFiles_Click(object obj, EventArgs evt) private void _refreshRecentFilesMenu() public void AddRecentFile(string fileNameWithFullPath) public void RemoveRecentFile(string fileNameWithFullPath) public MRUManager(ToolStripMenuItem parentMenuItem, string nameOfProgram, Action onRecentFileClick, Action onClearRecentFilesClick = null) }

类中有两个私有方法:

_refreshRecentFilesMenu()_onClearRecentFiles_Click()

当创建新的MRUManager对象时,构造函数会检查无效参数。如果有,它会抛出一个新的ArgumentException。然后调用_refreshRecentFilesMenu()来更新列表,以防之前在注册表中存储了任何条目。

类在注册表下存储最近文件的键是"HKEY_CURRENT_USER\SOFTWARE\{提供的程序名称}\MRU"。它将这个字符串存储在私有成员SubKeyName中。

每当调用AddRecentFile()时,它在该键下创建一个新的值。值的名称是数字,从0开始,一直到添加的数量。然后调用_refreshRecentFilesMenu()。

每当调用RemoveRecentFile()时,它在SubKeyName下搜索包含传递的文件名的值,并将其删除。然后调用_refreshRecentFilesMenu()。

_refreshRecentFilesMenu()调用{ToolStripMenuItem提供的}.DropDownItems.Clear(),然后使用注册表中的所有值重新填充它。它添加的每个最近文件菜单项都会传递一个指向提供的函数的EventHandler。然后它添加两个项目:一个分隔符和'清除列表'菜单项,当点击时,会运行私有方法_onClearRecentFiles_Click()。

_onClearRecentFiles_Click()执行三个操作:清除注册表中的最近文件,清除菜单项,并调用用户可能可选指定的函数。

以下是_refreshRecentFilesMenu()和_onClearRecentFiles_Click()的简化版本:

private void _refreshRecentFilesMenu() { string s; ToolStripItem tSI; RegistryKey rK = Registry.CurrentUser.OpenSubKey(this.SubKeyName, false); this.ParentMenuItem.DropDownItems.Clear(); string[] valueNames = rK.GetValueNames(); foreach (string valueName in valueNames) { s = rK.GetValue(valueName, null) as string; if (s == null) continue; tSI = this.ParentMenuItem.DropDownItems.Add(s); tSI.Click += new EventHandler(this.OnRecentFileClick); } if (this.ParentMenuItem.DropDownItems.Count == 0) { this.ParentMenuItem.Enabled = false; return; } this.ParentMenuItem.DropDownItems.Add("-"); tSI = this.ParentMenuItem.DropDownItems.Add("Clear list"); tSI.Click += new EventHandler(this._onClearRecentFiles_Click); this.ParentMenuItem.Enabled = true; } private void _onClearRecentFiles_Click_SIMPLIFIED(object obj, EventArgs evt) { RegistryKey rK = Registry.CurrentUser.OpenSubKey(this.SubKeyName, true); if (rK == null) return; string[] values = rK.GetValueNames(); foreach (string valueName in values) rK.DeleteValue(valueName, true); rK.Close(); this.ParentMenuItem.DropDownItems.Clear(); this.ParentMenuItem.Enabled = false; if (OnClearRecentFilesClick != null) this.OnClearRecentFilesClick(obj, evt); }

与原文的偏差

尽管本文中的MRUManager类是从头开始编写的,但它与原文的实现相似。例如,它仍然使用注册表来存储文件路径,并且它创建的GUI界面与原文非常相似。决定让MRUManager更加简洁,不包括像'maxNumberOfFiles'或'maxDisplayLength'这样的东西,但仍然足够功能强大,可以立即使用。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485