Behavior Service Overview
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.
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.
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.
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.
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.
A single adornment layer handles all selection UI Glyph objects.
A completely transparent body Glyph sits over the top of the control. Its behavior handles all mouse interaction.
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 ().
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
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.
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.
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.
The BehaviorService architecture is tied to the Windows Forms model and therefore does not support other display technologies, such as Web Forms.