Non-Maintenance Notice
This code will no longer be maintained. It is only by luck that I still happen to have Visual Studio 2003 installed and was able to test the latest changes. I will leave the article on Code Project just in case someone needs this code.
Introduction
As I've been teaching myself C#.NET, I've quickly learned it lacks many of the UI oriented features I've grown accustomed to with MFC. One glaring omission is the lack of the most recently used (MRU) file list functionality from the menu class. This class presents a stop-gap solution until Microsoft adds an integrated one to the menu classes and the .NET Framework.
A Visual Studio 2005 / .NET 2.0 version of this class has been created. The new article can be found here.
The MruMenu Class
The MruMenu
class displays a list of most recently used files in a popup menu. A derived class, MruMenuInline
, displays them as additional entries in a menu, or inline. In both cases, a number is displayed to the left of the file. Entries 1-10 allow you to use a number on the keyboard to select that entry.
Namespace
This class is in them oh so creatively named, JWC (Joe Woodbury Classes) namespace.
Constructors
MruMenu(MenuItem recentFileMenuItem, ClickedHandler clickedHandler)
MruMenu(MenuItem recentFileMenuItem, ClickedHandler clickedHandler,
int maxEntries)
MruMenu(MenuItem recentFileMenuItem, ClickedHandler clickedHandler,
String registryKeyName)
MruMenu(MenuItem recentFileMenuItem, ClickedHandler clickedHandler,
String registryKeyName, int maxEntries)
MruMenu(MenuItem recentFileMenuItem, ClickedHandler clickedHandler,
String registryKeyName, bool loadFromRegistry)
MruMenu(MenuItem recentFileMenuItem, ClickedHandler clickedHandler,
String registryKeyName, bool loadFromRegistry, int maxEntries)
recentFileMenuItem
This is the menu item that will serve as the anchor point for the MRU list. It must be created and inserted into the desired spot in a menu, before creating an MruMenu
instance.
clickedHandler
The delegate that will be called when one of the MRU entries is selected. The entry number (zero based) and the filename
will be passed to the handler.
registryKeyName
The name of a registry key MruMenu
will use to load and/or store the contents of the MRU list. If a key name is passed to the constructor, and loadFromRegistry
is true
, MruMenu
will attempt to load the files from the registry. However, to save the MRU list, you must call SaveToRegistry()
.
loadFromRegistry
If true
, MruMenu
will attempt to load the MRU list stored in the passed registry key. If the registry key does not exist, an exception will not be thrown.
maxEntries
The maximum number of entries to allow in the MRU list. Currently, for practical reasons, the number of entries is limited to be from 4 through 16. If _maxEntries
is not within this range, it will be adjusted up, or down, whichever is appropriate (an ArgumentOutOfRangeException
will not be thrown.)
Delegates
public delegate void ClickedHandler(int number, String filename)
number
- The MRU relative number of the entry that was clicked
filename
- The filename
of the entry that was clicked
Properties
Menu.MenuItemCollection MenuItems (ReadOnly)
The MenuItemCollection
where the MRU list is located.
int StartIndex (ReadOnly)
The menu index of the first MRU entry.
int EndIndex (ReadOnly)
The menu index immediately "after" the last MRU entry.
int NumEntries (ReadOnly)
The current number of MRU entries.
int MaxEntries (Read/Write)
The maximum number of MRU entries allowed. You can set the MaxEntries
to the range of 4 through 16. If the new maximum entries is less than the current number of entries, the oldest entries will be discarded.
int MaxShortenPathLength (Read/Write)
The maximum length of the path to allow in the menu, in characters. When setting, any value less than 16 will be changed to 16. The new length will have no effect on the current contents of the menu.
String RegistryKeyName (Read/Write)
Set
/Get
the registry key name where MRU list will be loaded/saved. No error checking is done to verify if the key is valid.
Static Methods
static String FixupEntryname(int number, String entryname)
Adds the entry number prefix and mnemonic (for entries 0-9) to the filename
. Note that the number is zero based, while the actually displayed numbering is one based.
static String ShortenPathname(String pathname, int maxLength)
If the pathname
is longer than maxLength
, it replaces consecutive path components ellipsis. It will always preserve the root of the path and at least three characters of the filename, which may cause the result to be longer than maxLength
.)
pathname
The pathname
to check and, possibly, shorten. The pathname
should be fully resolved and start with a drive letter or be a UNC path.
maxLength
The maximum length, in characters, of the resulting path.
Methods
int FindFilenameNumber(String filename)
Find the MRU relative number of the entry which matches filename
. This match must be exact except for case sensitivity.
Returns -1 if a matching entry cannot be found.
filename
The filename
to find.
int FindFilenameMenuIndex(String filename)
Find the menu index of the entry which matches filename
. This match must be exact except for case sensitivity.
Returns -1 if a matching entry cannot be found
filename
The filename
to find.
int GetMenuIndex(int number)
Returns the menu index of the entry at the MRU relative number.
String GetFileAt(int number)
Return the filename
stored at the MRU relative number
.
String[] GetFiles()
Returns the list of files in the MRU list. The most recent file will be at index zero.
void SetFiles(String[] filenames)
Replaces the MRU entries with filenames
. (Functionally equivalent to: RemoveAll(); AddFiles(filenames);
) The filenames
will be added such that the first string in the array will be topmost on the MRU list. (In other words, the entries will be added from the end to the beginning.)
void SetFirstFile(int number)
Makes the specified entry the first on the MRU list.
void AddFiles(String[] filenames)
Adds filenames
to the list of files. The filenames
will be added such that the first string in the array will be topmost on the MRU list. (In other words, the entries will be added from the end to the beginning.)
void AddFile(String filename)
Adds a filename
to the MRU list. If the entry exists, it will be moved to the first position. Otherwise it will be added in the first position. If the number of entries exceeds maxEntries
, the least recent file (the last one) will be removed.
Before being added, the filename
will first be resolved to an absolute path. The result will then be passed to the ShortenPathname
function. Despite the absolute path resolution, it is possible for multiple entries to refer to the same physical file.
filename
The filename
to add.
void AddFile(String filename, String entryname)
Adds entryname
to the MRU list and stores filename
with that entry. If the entry exists, it will be moved to the first position. Otherwise it will be added in the first position. If the number of entries exceeds maxEntries
, the least recent file (the last one) will be removed. Note that filename
will be used to determine whether an entry exists. Thus it is possible to have two identical entries in the MRU list, even though the associated filenames
are different.
void RemoveFile(int number)
Removes the entry at the MRU relative number.
void RemoveFile(String filename)
Removes the entry associated with filename
.
filename
The filename
to remove.
void RemoveAll()
Removes all MRU entries.
void LoadFromRegistry(String keyName)
Sets the registry key and loads the entries located at that key.
void LoadFromRegistry()
Loads the entries located at the stored key.
void SaveToRegistry(String keyName)
Sets the registry key and saves the entries to that key.
void SaveToRegistry()
Saves the entries located at the stored key.
Changes
17 July 2003
18 July 2003
- Added
SetFirstFile()
method
- Added code to
MruMenuDemo
to better demonstrate how to use MruMenu
- Added section describing namespace
17 December 2003
- Added an empty constructor to the internal class
MruMenuItem
. This prevents an exception when using the class with MDI applications.
16 October 2007
- Fixed a bug in
FixupPrefixes
where the first character was being stripped (thanks to shostakovich55 for that catch and his elegant solution.)
- Constructor now calls property to set
MaxEntries
which does range checking