您的位置:首页 > 移动开发

Add Most Recently Used Files (MRU) List to Windows Applications(在桌面应用程序中添加最近访问文件列表)

2012-06-26 12:34 363 查看
原文地址链接:

http://www.codeproject.com/Articles/407513/Add-Most-Recently-Used-Files-MRU-List-to-Windows-A



Introduction

I've written applications in the past in which users need to open files and have found that they usually re-open the same files over and over. So instead of forcing them to browse and open the same file over and over again, I decided to create an MRUManager,
to make things easier.

在之前我写过的一些应用程序中,用户需要打开文件,他们发现经常需要重复第打开同一个文件。因此,强制他们去重复地浏览并打开同一个文件不是合理的选择,我决定创建一个MRU管理器(Most Recently Used经常最近访问文件)来让打开重复文件的操作更方便。

Background

It uses the Windows Registry to store the paths of the recently opened files, so if you're not familiar with the registry,
Wikipedia would be a good place to start. As a reference, use Microsoft's documentation of the C# class Microsoft.Win32.Registry if
you're unsure about the registry manipulation methods.

实现原理,使用Windows注册表来存储最近打开的文件的路径。因此,如果你对注册表不够熟悉,Wikipedia将会是你开始学习的一个好地方。

如果你对注册表操作的方法不够了如指掌,使用微软C#Microsoft.Win32.Registry 类的文档作为参考。

Using the code

You can use the MRUManager class right away (at your own risk, of course) without having to modify the code. There are only a few requirements.

你可以直接使用我写的MRUManager类(当然是在你自己的磁盘上)而不需要修改代码,仅有以下几条要求。

PS:作者很幽默,他的意思是可以直接复制它的MRUManager类代码到你的应用程序中,我想没有人会想他所担心的那样会尝试通过URL等途径来链接作者磁盘上的该类。

Using Visual Studio, create a
ToolStripMenuItem
to be used as the parent menu item of the recent files list. Don't put sub-menu items in this one as they will be removed by the MRUManager.
Create a method with this prototype.
void myOwnRecentFileGotClicked_handler(void obj, EventArgs evt)

This method will be called when the user clicks on one of the recent items.

Optional: create a method that has the same parameters as the previous one. This will be called after a user clicks 'Clear list'.

Once you have those, simply create a new instance of the
MRUManager
class, like so

private MRUManager mruManager;

private void Form1_Load(object sender, EventArgs e)
{
this.mruManager = new MRUManager(
//the menu item that will contain the recent files
this.recentFilesToolStripMenuItem,

//the name of your program
"myProgram",

//the funtion that will be called when a recent file gets clicked.
this.myOwn_recentFileGotClicked_handler,

//an optional function to call when the user clears the list of recent items
this.myOwn_recentFilesGotCleared_handler);
}

Afterwards, there are two public methods that can be called:

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

Examples of their usage:

If a user opens (or even saves) a file:

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;

//Now give it to the MRUManager
this.mruManager.AddRecentFile(openedFile);

//do something with the file here
MessageBox.Show("Through the 'Open' menu item, you opened: " + openedFile);
}


When the user clicks on a recent file, but it doesn't exist.

Inside the Class

Below is an overall view of the class:

public class MRUManager
{
private string NameOfProgram;
private string SubKeyName;
private ToolStripMenuItem ParentMenuItem;
private Action<object, EventArgs> OnRecentFileClick;
private Action<object, EventArgs> 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<object, EventArgs> onRecentFileClick,
Action<object, EventArgs> onClearRecentFilesClick = null
)
}

There are two private methods that do some of the work for the class:
_refreshRecentFilesMenu()
and
_onClearRecentFiles_Click()
.

When a new
MRUManager
object is instantiated, the constructor checks for invalid parameters. If there are any, it throws a new
ArgumentException
. It then calls
_refreshRecentFilesMenu()
to update the list, in case there were any entries previously stored in the registry.

The registry key that the class stores recent files under is "HKEY_CURRENT_USER\SOFTWARE\{program name that you supplied}\MRU". It stores this string in a private member,
SubKeyName
.

Whenever you call
AddRecentFile()
, it creates a new value under that key. Value names are numerical and go from 0 to as many as you add. It then calls
_refreshRecentFilesMenu()
.

Whenever you call
RemoveRecentFile()
, it searches for a value under SubKeyName that contains the file name that you pass in and deletes it. It then calls
_refreshRecentFilesMenu()
.

_refreshRecentFilesMenu()
calls
{ToolStripMenuItem that you supplied}.DropDownItems.Clear()
and then repopulates it with all the values in the registry. Each recent file menu item that it adds gets passed an EventHandler
that points to the function that you supplied. It then adds two items: a separator and 'Clear list' menu item, which, when clicked, runs the private method
_onClearRecentFiles_Click()
.

_onClearRecentFiles_Click()
does three things: clears the registry of recent files, clears the menu item and calls the the function that the user may have optionally specified.

Simplified versions of
_refreshRecentFilesMenu()
and
_onClearRecentFiles_Click()
are shown below.

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);
}


Deviations from the Original Article

Although the MRUManager class in this article was written from scratch, it bears a resemblance to the original article's implementation. For example, it still uses the registry to store file paths and the GUI interface it creates is much like the original.
I decided to make my MRUManager more minimalistic, by not including things like '
maxNumberOfFiles
' or '
maxDisplayLength
', yet still functional enough to use right away.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐