Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Add Context Sensitive Functionality to a Windows Forms Control

0.00/5 (No votes)
10 Feb 2006 1  
Replace the right-click menu with something graphical.

Before Visual Cues Displayed

After Visual Cues Displayed

Introduction

I am currently in the early stages of developing an application that allows the user to create a diagram using a library of pre-defined graphical elements. Each of these graphical elements has functionality that becomes available when the context is on an instance of that element. I decided that this Context Sensitive functionality should be provided by additional controls associated to the graphical element, not via a right click menu. This article describes how I designed and developed a solution to this problem by creating a library that provides a way of attaching one or many sets of Visual Cues to a parent control and then manages the visibility of these by handling certain mouse events of the parent control.

At the moment, the library provides the ability to create a Cues object, register this with the parent Control, and then add any number of sets of Visual Cues to that Control. Each set of Visual Cues is based on a specified model Control, and each individual Visual Cue can be located either at some pre-defined point around the parent Control or at an absolute position. The visibility of the Visual Cues is handled by the MouseEnter and MouseLeave events, where Show and Hide timers are started and stopped accordingly. It also ensures that any Visual Cues attached to a parent Control that may change its position at run-time will follow that Control by handling the LocationChanged event.

Sample Application

As well as the Visual Cues library, the source code contains a small application, called CueTest, that demonstrates some Visual Cues.

  • The CueTest form contains a number of controls, each of which have some Visual Cues attached.
  • The Drag 'n Drop Panel contains two draggable controls, each with a set of Corner Cues, demonstrating the repositioning. There is also a Help (?) button.
  • The Button has a set of Visual Cues attached with the Click event handled so that a Messagebox can be displayed.
  • The TextBox has three sets of Visual Cues attached, one containing a Clear button, one containing a choice list, each which interact with their parent control. The final set contains a Help (?) button.
  • The PictureBox has three sets of Visual Cues attached, the first set containing cues located at the corners, these have no functionality. The second set has a Help (?) button, and the third has two image navigation buttons.

Some of the Visual Cues are based on native .NET controls, some are extended versions that I have created. The visibility of each set of Visual Cues is controlled by the mouse events of its parent and their Show and Hide timers.

Class Descriptions

Cues (extends ArrayList). The Cues class is the top-level class of the Visual Cues hierarchy, that maintains a collection of CueList objects. Its constructor receives a reference to the parent Control that is used to register the Cues object. The Cues class contains the code that handles the MouseEnter, MouseLeave, and LocationChanged events of the parent Control. It contains a number of overloaded methods that return a CueList object, allowing for the creation of Visual Cues in a variety of pre-defined or absolute positions.

CueList (extends ArrayList). The CueList class maintains a collection of CueAdaptor objects. It provides a means to reference a set of Visual Cues attached to a parent Control. It contains the public methods StartShow(), StopShow(), StartHide(), and StopHide() that control the Visual Cue visibility timers.

CueAdaptor. The CueAdaptor class forms part of the implementation of the Adaptor Pattern, allowing a Windows.Forms.Control to participate as a Visual Cue without being extended or implementing any specific interfaces. Its constructor receives references to both the parent Control and the Visual Cue control. The CueAdaptor class handles the event passage between the parent Control and the Visual Cue and vice versa.

CuePosition. The CuePosition class maintains attributes that describe the location of a Visual Cue, relative to its parent Control. This class also handles the coordinate calculation and Visual Cue repositioning if its parent location changes at runtime.

Visual Cues Class Diagram

Visual Cues Class Diagram

Creating a set of Visual Cues

To add a set of Visual Cues to a Windows.Forms.Control takes up to five steps:

Step 1. Create an instance of Cues and register the parent Control. Cues extends System.Collections.ArrayList and is used to store any number of sets of Visual Cues attached to the parent control con.

RestlessCues.Cues cues = new RestlessCues.Cues(con);

Step 2. Create an instance of the Windows.Forms.Control derivative that will be used as a model for the Visual Cues attached to the parent control.

System.Windows.Forms.Button cue = new Button();

Step 3. If you need to get a handle on the list of Visual Cues when they are created then you need a CueList. You will need this if you need to handle any events raised by the Visual Cue control.

CueList buttonList;

Step 4. Create a set of Visual Cues and attach them to the parent control. This example will create a single Visual Cue based on the type "cue", at an absolute position based on the parent control (con) coordinates. The other attributes set the width (45) and height (20) of the Visual Cue, the gap (1) between the parent control and the Visual Cue, and finally two timer values for show delay (10) and hide delay (1000).

buttonList = cues.AddCue(cue, new Point(con.Width - 50, 
             con.Height - 25), 45, 20, 1, 10, 1000);

Each Visual Cue is created based on the Type of the model specified.

// Get Base Type of model Cue

Type type;
type = cueModel.GetType();

System.Windows.Forms.Control cue;
cue = (System.Windows.Forms.Control)Activator.CreateInstance(type);

The library contains a number of Add Cue routines for creating pre-located sets of Visual Cues, in the corners, North, South, East and West as a single set, or N, S, E, W individually.

cues.AddCornerCues(cue, 7, 4, 0, 10, 1000);
cues.AddCue(cue, CueDirection.N, 100, 20, 1, 10, 1000);
cues.AddSideCues(cue, 10, 10, 1, 10, 1000);

Step 5. Using the CueList, iterate the CueAdaptors collection to register event handlers or alter attributes of the Visual Cue control.

foreach (CueAdaptor ca in buttonList)
{
    ca.ClickEvent += new CueClickEventHandler(TextBoxClearButton_Click);
    ca.CueControl.Text = "Help";
}

Sequence Diagrams

The following Sequence Diagram illustrates the logic flow resulting from handling the MouseEnter and MouseLeave events.

Operation of the Visual Cues

The diagram highlights the importance of the Show and Hide timers. These timers, associated with a CueList, are started and stopped by the MouseEnter and MouseLeave events of the parent control. They are necessary for two reasons, firstly they provide the developer with a way of setting the delays between the context sensitive functionality becoming available and lost, they also overcome the fact that the MouseLeave event fires as soon as the parent control loses mouse focus that would result in the Visual Cues being hidden before they could gain focus.

Points of interest

The Visual Cues are added to the container that contains the parent control, therefore it is important that the parent has been added to a container before initializing the Visual Cues.

The file handling of the images is a bit primitive, the application requires them to be in the same folder the app is run from, and they have to be named Image0.jpg and Image1.jpg.

One thing I am uncertain of is whether a C# (or any .NET) application will suffer from too many controls on a form, I know Visual Basic had a limit. My library obviously encourages you to add more controls.

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