Click here to Skip to main content
12,552,615 members (59,223 online)
Click here to Skip to main content
Add your own
alternative version


125 bookmarked

Creating an Extensible User Interface with .NET, Part 2

, 15 Dec 2002 CDDL
Rate this:
Please Sign up or sign in to vote.
Accessing application level user interface elements from plug-in components.


In Part 1, I described an architecture that allows you to create user interface plug-ins that can be loaded at runtime. In this document, I will describe methods for accessing application level user interface elements from the plug-ins. Please see Creating an Extensible User Interface with .NET, Part 1 before reading this article.


Some user interface elements naturally belong to the shell and should not reside in the plug-in. By convention, a status bar should run the entire width of the application window. Putting a status bar inside a plug-in would look odd and out of place. The main menu is another UI element that belongs to the shell application, but should be accessible from a plug-in. The following two examples show methods you can use to provide access to these two user interface elements.

Adding a StatusBar to the shell.

In this first example we will add a status bar to the shell and give the plug-ins a reference to one of the status bar's panels. We also include a helper function for placing text into the status bar panel.

Base class changes.

First we will add the needed code to the plug-in base class located in PlugIn.cs.

  • Add a local variable to hold the StatusBarPanel.
    /// <span class="code-SummaryComment"><summary>
  • Next add a property to set and get the StatusBarPanel.
    /// <span class="code-SummaryComment"><summary>
  • And finally add a helper function that a plug-in can call to set the text in the StatusBarPanel. Note that we check that the _StatsPanel has been set before assigning the text.
    /// <span class="code-SummaryComment"><summary>

Shell application changes

Now we can modify the shell application.

  • Add a StatusBar control to the form.
  • Add a StatusBarPanel to the StatusBar.
  • Within AddPlugIn set the plug-in’s StatusPanel property to the StatusBarPanel you just added.
/// <span class="code-SummaryComment"><summary>

Plug-in modifications

  • Finally add code to your plug-in to show its status: Here we just display "Over the Label" when the mouse is hovering above label1.
    private void label1_MouseEnter(object sender, System.EventArgs e)
        ShowStatus("Over the Label");
    private void label1_MouseLeave(object sender, System.EventArgs e)

Adding menus to the shell

It is very desirable for each plug-in to provide its own set of menus. The menus should only appear when the plug-in is visible. Doing this is a little more complicated than the previous example. The overriding goal of this design is that the plug-in should not need to manage its own menus. When the plug-in is not visible, then its menus should be automatically removed from the shell's main menu.

In this example, the plug-in will define its menus and place a reference to them in the base class. The base class will then call a function in the shell to install or delete the menus. The base class will use its own visibility property to determine if the menus should be installed or deleted.

Base class changes.

Again we will start by modifying the plug-in base class.

  • Add a declaration for a SetMenuDelegate. A delegate declaration defines a reference type that can be used to encapsulate a method with a specific signature. Here it defines a function that will be supplied by the shell application to add and delete items to its main menu.
    /// <span class="code-SummaryComment"><summary>
  • Declare an instance of the SetMenuDelegate delegate. This is where the shell application will place a reference to the function that will add and delete menu items.
    /// <span class="code-SummaryComment"><summary>
  • Since we are going to let the base class manage the menus, we need a place to store them.
    /// <span class="code-SummaryComment"><summary>
  • And we need a property to set them.
    /// <span class="code-SummaryComment"><summary>
  • Override the OnVisibleChanged function.

    This is where all the magic happens. When the plug-in's visibility changes, the base class will call the shell and let it add or delete the menus. After we have called SetMenu, we call base.OnVisibleChanged(e) so that normal processing continues. If we didn't do this, the plug-in would never receive "VisibileChanged" events.

    /// <span class="code-SummaryComment"><summary>

    If your shell application shows multiple plug-ins simultaneously, you could override OnEnter and OnLeave to show the menus only when the plug-in has the focus.

Shell application changes

Next we modify the shell application to handle calls through the SetMenuDelegate.

  • Add a MainMenu control to the form and add any menus required for the shell application.
  • Add a function to add and delete menus. This function must match the signature of the SetMenuDelegate in the plug-in base class.
    /// <span class="code-SummaryComment"><summary>
  • In AddPlugIn, set the plug-in’s SetMenu property to the PlugIn_SetMenu function.
    /// <span class="code-SummaryComment"><summary>

Adding menus to the plug-in.

You cannot add a MainMenu to a UserControl. You will need to code your menus by hand. Due to all the overloaded MenuItem constructors, this is quite easy to do.

  • First declare your top-level menus.
    private System.Windows.Forms.MenuItem FileMenu;
    private System.Windows.Forms.MenuItem EditMenu;
  • In the constructor for the plug-in, you can now create your complete menus.

    Here we create a "File" menu with 2 sub-items, "New" and "Save" and an "Edit" menu with "Cut", "Copy" and "Paste". Then we bundle the top-level menus into an array and assign it to the MenuItems property.

    // Create a "File" menu
    FileMenu = new MenuItem("File",new MenuItem[]
            new MenuItem("New",new EventHandler(menuNew_Click)),
            new MenuItem("Save",new EventHandler(menuSave_Click))
    // Create an "Edit" menu
    EditMenu = new MenuItem("Edit",new MenuItem[]
            new MenuItem("Cut",new EventHandler(menuEdit_Click)),
            new MenuItem("Copy",new EventHandler(menuEdit_Click)),
            new MenuItem("Paste",new EventHandler(menuEdit_Click))
    // Set the MenuItems
    this.MenuItems = new System.Windows.Forms.MenuItem[]

    Now when this plug-in becomes visible, its menus will be added to the application's menus. The events generated when a menu selection is made will fire directly to event handlers in the plug-in.


With the addition of these two methods of communicating with the shell application, you should have a complete framework for creating an application with an extensible user interface.


In the file, config.xml file is located in both the Release and Debug directories of the "Shell" application. These files contain the absolute pathname to the OurControls.dll including a drive letter. You will need to modify these paths for your local system.


This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)


About the Author

Keith Jacquemin
Web Developer
United States United States
I am a senior software developer located in Phoenix, AZ. I have a wide range of experience using Microsoft development technologies and have clung to the bleeding edge of their developments tools since Windows 3.1. I am now lacerating myself on .Net.

I am currently available for any contract or permanent assignments.

You may also be interested in...


Comments and Discussions

QuestionSome code parts of the text are not shown! Pin
Hooman7-Apr-16 11:41
memberHooman7-Apr-16 11:41 
QuestionCan it be used to Web Application Pin
MHSrinivasan3-Oct-08 0:59
memberMHSrinivasan3-Oct-08 0:59 
AnswerRe: Can it be used to Web Application Pin
Keith Jacquemin3-Oct-08 3:45
memberKeith Jacquemin3-Oct-08 3:45 
GeneralNice work Pin
JoeIsTheMan30-Jan-07 12:37
memberJoeIsTheMan30-Jan-07 12:37 
Generalgood stuff Pin
william keeling16-Jan-04 18:46
memberwilliam keeling16-Jan-04 18:46 
GeneralRe: good stuff Pin
Husein29-Jan-04 13:32
memberHusein29-Jan-04 13:32 
GeneralMerging Menus Pin
Heath Stewart29-May-03 21:47
editorHeath Stewart29-May-03 21:47 

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.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.161021.1 | Last Updated 16 Dec 2002
Article Copyright 2002 by Keith Jacquemin
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid