Behavior Service Overview

Caution

This content was written for .NET Framework. If you're using .NET 6 or a later version, use this content with caution. The designer system has changed for Windows Forms and it's important that you review the Designer changes since .NET Framework article.

The BehaviorService manages user interface in a designer. It provides a uniform way to manipulate user interface elements such as mouse-related events, menu commands, and OLE drag-and-drop operations at design time.

Managing User Interface at Design Time

A key aspect of authoring a custom design-time experience is managing user interface. You provide a design-time experience for your custom control by authoring a custom designer.

As a designer developer, you can create your own user interface layers, called adorners. Within each layer surface you create your own Glyph types for painting, dragging, and other UI operations. Each Glyph may have an associated Behavior type. A Behavior is a class that has overloads for all user input, including menu commands, mouse movements, and OLE drag-and-drop operations. Behavior objects can also be added independently of a Glyph object, so that they can hook into the general user input for the entire designer. All three of the previously mentioned features are implemented with the Behavior type.

Note

You must add a reference to the design-time assembly, System.Design.dll. This assembly is not included in the .NET Framework 4 Client Profile. To add a reference to System.Design.dll, you must change the project's Target Framework to .NET Framework 4.

In the .NET Framework version 1.1, some events, such as OnMouseDragBegin, were exposed by the ControlDesigner class. In this model, much of the UI designer logic is implemented in the EventHandler. Because there are several designated areas on a control that a user may manipulate, this model required that you write a great deal of supporting logic.

The Behavior type addresses this situation. The BehaviorService consists of two parts. The following table shows the parts with descriptions of each.

Part

Description

Stack of Behavior classes

Each class has methods related to menu commands, OLE drag-and-drop operations, mouse events, and so on. The class at the top of the stack is the active Behavior, and all user input is routed to that Behavior.

Adorner and Glyph objects

An Adorner is an invisible layer between the design surface and the user. An Adorner can contain Glyph objects, which are lightweight rendered objects. A Glyph can be hit-tested by the behavior service and it can optionally expose a Behavior object that becomes the active Behavior for as long as the Glyph reports true from its hit test.

While the Windows Forms Designer still supports the original ControlDesigner overrides for drags and mouse moves, these actions are implemented as Behavior objects. The following table shows the elements in the designer for a simple control that has the normal set of drag handles.

Behavior element

Description

Selection Adorner

A single adornment layer handles all selection UI Glyph objects.

Body Glyph

A completely transparent body Glyph sits over the top of the control. Its behavior handles all mouse interaction.

Grab Glyph

Grab Glyph objects draw the grab handles for the control. Their Behavior objects control dragging operations.

Extending the Design-Time User Interface

The BehaviorService model enables new functionality to be easily layered on an existing designer user interface. New UI remains independent of other previously defined Glyph and Behavior objects. For example, the smart tags on some controls are accessed by a Glyph in the upper-right-hand corner of the control (Smart Tag Glyph).

The smart tag code creates its own Adorner layer and adds Glyph objects to this layer. This keeps the smart tag Glyph objects separate from the selection Glyph objects. The necessary code for adding a new Adorner to the Adorners collection is straightforward.

    behaviorService = (BehaviorService)serviceProvider.GetService(typeof(BehaviorService));
    designerActionAdorner = new Adorner();
    behaviorService.Adorners.Add(designerActionAdorner);
    Glyph dag = new DesignerActionGlyph(/*...*/);
    designerActionAdorner.Glyphs.Add(dag);

Glyphs and Behaviors

The Glyph type is simple. If you need complex functionality, you add it to your own class derived from the Glyph.

Glyph objects may have Behavior objects, but they are not required. A Glyph with no Behavior objects has a Behavior property that returns null.

A Behavior has a method for each supported user interaction. For example, the base Behavior class has methods for supporting drag-and-drop operations like OnDragEnter and OnGiveFeedback.

Most methods return a Boolean value indicating whether the event was handled. Drag events have a value in the DragEventArgs parameter. Individual menu items can be added or removed by returning them from the FindCommand method. The FindCommand method works in conjunction with the DisableAllCommands property to specify how MenuCommand objects interact with the behavior.

Adorners

An Adorner can be viewed as a proxy between user-interface related elements, which consist of Glyph objects, and the BehaviorService.

Each Adorner can be enabled and disabled. Only enabled Adorner objects will receive hit test and paint messages from the BehaviorService.

When an Adorner is added to the BehaviorServiceAdornerCollection of the BehaviorService, the collection sets the BehaviorService property so that the Adorner can call back to the BehaviorService.

Calling the Adorner object's Invalidate method forces its associated BehaviorService to refresh the Adorner window

Pushing Behaviors

The easiest way for you to add Behavior objects to the behavior stack is by using Glyph objects, but this is not the only way. Glyph objects themselves may push Behavior objects on the behavior stack, and you may also push Behavior objects directly on the behavior stack. Consider the case in which you want to drag a grab handle around on the design surface. Instead of you writing logic to track when the user is dragging, the Glyph itself performs the following actions in sequence with the behavior stack.

  1. The Glyph has an associated Behavior that responds to a mouse-down gesture.

  2. When the mouse button is pressed, the Glyph pushes a new Behavior on the behavior stack. This Behavior handles mouse-move and mouse-up events. It may also disable all menu commands so that there is no way for keyboard shortcuts or other commands to occur for the duration of the drag.

  3. When the mouse button is released, the Behavior finalizes the movement gesture and pops itself off of the behavior stack. This automatically restores the previous Behavior.

Note

The BehaviorService architecture is tied to the Windows Forms model and therefore does not support other display technologies, such as Web Forms.

See Also

Reference

BehaviorService

Glyph

Adorner

EventHandler

Other Resources

Extending Design-Time Support