Click here to Skip to main content
15,867,141 members
Articles / Desktop Programming / Windows Forms
Article

Most Recently Used (MRU) Component

Rate me:
Please Sign up or sign in to vote.
4.38/5 (4 votes)
5 Nov 20045 min read 110.5K   656   52   14
A Most Recently Used component written in C#.

Sample Image - MRUHandler1.jpg

Introduction

In an effort to learn C#, I started to redevelop an application program that I had written in Java. I quickly realized, like many others, that there was no Most Recently Used functionality built into the .NET framework.

The MRUHandler component displays a most recently used (MRU) menu list. Multiple MRUHanlder components can be used in the same application without colliding. For example, the image above depicts the demo program supporting an MRU history for files and a MRU history for viewed URLs. As well, it will work within the context of a Multiple Document Interface (MDI) application.

Background

After searching CodeProject, I found two reference articles: Joe Woodury's Most Recently Used (MRU) Menu class in C# and Alex Farber's Add Most Recently Used Files (MRU) List to Windows Applications. Unfortunately, neither of these appealed to me, as I was looking for an approach that would allow me to "plug-in" the MRU functionality. After reading Philip Davis’ article Extended Interface for Status Message, I decided to try developing this functionality as a custom Component.

MRUHandler Overview

Properties

The properties can only be set from the Designer or during the framework initialization. I was unsuccessful in finding a way to serialize the properties from the designer into the runtime, as you were able to do in Visual Basic 6.0. What I ended up doing was implementing the ISupportInitialize interface. This interface allows the MRUHandler to trap the start and end of the initialization and set an initializing flag. If anyone knows how to get the framework to do this, I would sure appreciate the input.

C#
public void BeginInit() {_isInitializing = true;}
public void EndInit() {
    _isInitializing = false;
    if (!DesignMode) {
        if (_mruItem == null) {
            throw new Exception("The property 'MruItem' item cannot be set to null");
        }
        RebuildMenu();
    }
}

Each of the properties then throws an exception if the _isInitializing flag is not set or the component is not in Design mode.

C#
public MenuItem MruItem {
    get{ return _mruItem;  }
    set{ 
        if (!DesignMode && !_isInitializing) {
            throw new Exception("The 'MruItem' can be only set in Design Mode");
        }
        _mruItem = value; 
    }
}

Available Properties

  • DisplayLength: The maximum length of the MRU entry file name when displayed.
  • MaxFiles: The maximum number of files to be maintained in the MRU History.
  • MRUItem: The menu item that is the place holder for the history list (when the style is Inline) or the parent menu item (when the style is Popup).
  • MRUStyle: Enumerated type to indicate if the MRU history should be displayed inline or as a popup menu.
  • ShowShortItem: Boolean value to indicate whether the display name should be compressed. If this is false, then the DisplayLength property is ignored.
  • StorageName: Provides a name for the file or registry key that is used to persist the MRU history. If the StorageType property is File or IsolatedStorage, the complete file name is generated using the product name (Application.ProductName) and this property, and the extension of the file is .mru. If the StorageType is Registry, this property is used to create a subkey under the application user data registry (Application.UserAppDataRegistry).
  • StorageStyle: Enumerated property to determine the location of the persistent storage used to save the MRU history information. Values are:
    • IsolatedStorage: The MRU history is stored using the .NET Isolated Storage facilities.
    • File: The MRU history is stored on the file system in the executable path (Application.ExecutablePath).
    • Registry: The MRU history is stored using the Win32 Registry. The values are added to the key specified by the StorageName property.

Public Methods

  • AddRecentlyUsedFile:
    The maximum length of the MRU entry file name when displayed.

Events

  • MRUItemClicked: The maximum length of the MRU entry file name when displayed.

Using the MRUHandler Component

Once the MRUHandler is installed in Visual Studio, adding MRU support to your application is as simple as dragging the component on to the main window and choosing which menu item is to be used as the MRU history placeholder. It is a good idea to have named this menu item something meaningful in order to assist in finding it in the list.

Image 2

Once you have chosen the menu item, then create the MRUItemClicked handler.

C#
private void OnMRUItemClicked(object sender, 
        MostRecentlyUsedHandler.MRUItemClickedEventArgs e) {
    DoFileOpen(e.File);
}

The MRUItemClickedEventArgs has a property File that contains the path name of the file that corresponds to be opened from the MRU history. In the demo program, DoFileOpen reads the file and opens the child window to display the contents.

The last step is to provide the mechanism that allows the application to tell the MRUHandler which file paths to keep track of and display. This is done by calling the AddRecentlyUsedFile method and passing the file path name that was just opened.

C#
private void DoFileOpen(string fileName) {
    FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
    Child form = new Child(fs);
    form.MdiParent = this;
    form.Show();
    mruHandler1.AddRecentlyUsedFile(fileName);
}

Points of Interest

Setting the modifier of the DataSet

When persisting the MRU to the file system, I had used a DataSet object to define an XML schema and do the actual transfer of information between the file system and the MRUHandler. I found that the default implementation provided by Visual Studio sets the access modifier of the generated class to public. The result was that MRUListFile would show up on the Toolbar as a component. It took a while, but I was able to change the access modifier of the generated class by going to the class view and selecting the properties of MRUListFile.xsd. I was then able to change the modifier to internal, which effectively hid this class in the designer.

Image 3

Build Versioning

I found that each time I rebuilt the application that contains the MRUHandler, the MRU history would be reset to empty when I was using a StorageType with a value of Registry. It turns out that the Application.UserAppDataRegistry refers to an application subkey that contains the Visual Studio generated version number. If this is a problem, it would be quite simple to modify the code to remove the version number from the key.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWork with ToolStripMenuItems? Pin
CJMUK25-Nov-09 1:07
CJMUK25-Nov-09 1:07 
Generallast file open Pin
mr_view28-Mar-09 11:32
mr_view28-Mar-09 11:32 
QuestionCan I Get Just the Most Recently Used Files? Pin
jasmarc17-Mar-09 9:30
jasmarc17-Mar-09 9:30 
GeneralFile not found - Storing to file Pin
pk_fox15-Feb-06 2:58
pk_fox15-Feb-06 2:58 
GeneralRe: File not found - Storing to file [modified] Pin
mad-matt30-Apr-09 9:32
mad-matt30-Apr-09 9:32 
Questionupdate for .NET 2.0 menuStrip control? Pin
hungpvtn17-Jan-06 1:12
hungpvtn17-Jan-06 1:12 
AnswerRe: update for .NET 2.0 menuStrip control? [modified] Pin
George Birbilis23-Feb-07 2:30
George Birbilis23-Feb-07 2:30 
GeneralBug with MRU File storage Pin
attrixx22-May-05 23:41
attrixx22-May-05 23:41 
GeneralFile not found Pin
TJO119-Nov-04 16:23
TJO119-Nov-04 16:23 
GeneralRe: File not found Pin
Tim Almdal19-Nov-04 17:27
Tim Almdal19-Nov-04 17:27 
GeneralRe: File not found Pin
codegalaxy11-Mar-05 9:14
codegalaxy11-Mar-05 9:14 
Generalcode change in saveToRegistry() Pin
hans_nl11-Nov-04 23:52
hans_nl11-Nov-04 23:52 
GeneralRe: code change in saveToRegistry() Pin
Tim Almdal12-Nov-04 19:01
Tim Almdal12-Nov-04 19:01 
GeneralRe: code change in saveToRegistry() Pin
mchumph18-Nov-04 1:46
mchumph18-Nov-04 1:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.