Services

This tutorial describes the Diagramming Framework Services.

The Diagramming Framework exposes a set of services that control and configure different diagramming tools and features. This is why the services come in handy in scenarios requiring significant customizations in the default behavior of the RadDiagram and its elements.

Service Locator

In order to manipulate, change or access a Diagramming Service, you have to use the RadDiagram.ServiceLocator. This property allows you to get a service instance, register new service or register the default diagramming services. The members exposed by the ServiceLocator are listed below:

  • RegisterDefaultServices() - this method registers the default Diagramming services. However, please note that the RadDiagram constructor internally calls this method during initialization. This is why the method is usefull mostly in scenarios where custom services are registered within a RadDiagram instance and you need to dynamically revert back to the default services.

        xDiagram.ServiceLocator.RegisterDefaultServices(); 
    
        xDiagram.ServiceLocator.RegisterDefaultServices() 
    
  • GetService() where T represents a service interface - this method returns a service instance used by a RadDiagram. The type parameter allows you to specify the interface of the service you need to access. For example, if you want to get the resizing service currently used in a RadDiagram instance, you need to ask for the service implementing the IResizingService interface:

        xDiagram.ServiceLocator.GetService<IResizingService>(); 
    
        xDiagram.ServiceLocator.GetService(Of IResizingService)() 
    
  • Register(T service) - this method allows you to register a new service in a RadDiagram. Please note that the type parameter T represents the service interface type, while the method argument allows you to provide a new service class. For instance, if you create a custom resizing service, you can register it in a RadDiagram instance:

        public class CustomResizingService : ResizingService 
        { 
            public CustomResizingService(IGraphInternal graph):base(graph) 
            { 
            } 
     
            ... 
        }    
     
        public partial class Services : UserControl 
        { 
            public Services() 
            { 
                InitializeComponent(); 
     
                xDiagram.ServiceLocator.Register<IResizingService>(new CustomResizingService(this.xDiagram)); 
            } 
        } 
    
        Public Class CustomResizingService 
            Inherits ResizingService 
            Public Sub New(graph As IGraphInternal) 
                MyBase.New(graph) 
            End Sub 
        End Class 
     
        Public Partial Class Services 
            Inherits UserControl 
            Public Sub New() 
                InitializeComponent() 
     
                xDiagram.ServiceLocator.Register(Of IResizingService)(New CustomResizingService(Me.xDiagram)) 
            End Sub 
        End Class    
    

    When registering a new SerializationService, you also have to recreate and register the DataTransferService in the service locator:

        xDiagram.ServiceLocator.Register<ISerializationService>(new CustomSerializationService(this.xDiagram)); 
        xDiagram.ServiceLocator.Register<IDataTransferService>(new DataTransferService(this.xDiagram)); 
    
        xDiagram.ServiceLocator.Register(Of ISerializationService)(New CustomSerializationService(Me.xDiagram)) 
            xDiagram.ServiceLocator.Register(Of IDataTransferService)(New DataTransferService(Me.xDiagram)) 
    
  • ServiceRegistered - this event occurs when a service is registered. You can handle it to keep track of the services changes in a RadDiagram instance.

AdornerService

This service manages the ManipulationAdroner and specifically how it should be rendered and where it should be displayed. The service implements the IAdornerService interface.

The AdornerService class exposes the following virtual methods, which can get overridden in order to customize the behavior of the service:

  • UpdateAdornerBounds - this method updates the bounds of the ManipulationAdroner. It has two different overloads - the first one allows you to pass the new bounds through a Rect argument, while the second overload of the method allows you to provide position (argument of type Point), Width and Height that are used to calculate the new bounds of the ManipulationAdroner.

  • UpdateAdornerAngle - this method determines the rotation angle of the ManipulationAdroner.

DataTransferService

This service handles:

  • clipboard operations within the RadDiagram

  • application-level drag and drop operations between a RadDiagram and another control

  • drag and drop operations between the RadDiagram and elements from external applications

The DataTranferService implements the IDataTransferService interface. It exposes the following virtual methods, which can get overridden in order to customize the behavior of the service:

  • HandleDrop - this method handles the transfer of data when there is a drop action. This can be both an internal drop (from one control to another within the same application) as well as an external drop operation (from one application to another or from the file system to an application).

  • HandlePaste - this method handles the transfer of data when a copy-paste or cut-paste operation is performed.

  • CreateShapeFromImage - this method creates a RadDiagramShape for a given image.

DraggingService

This service manages the translation of items on the surface. It exposes the following members:

Events:

  • StartDragging - occurs when user has done MouseDown on top of an item and has moved the mouse further than the DiagramConstants.StartDragDelta constant.
  • Dragging - invoked on every MouseMove while the mouse is still pressed and the StartDragging has occured.

    If grid snapping is activated this event will be invoked when a new snapped position is available.

  • CompleteDragging - occures on mouse up if the StartDragging has been raised.

The following events are only triggered for items that implement IDragDropAware interface. Currently, only the RadDiagramContainerShapes implement this interface by default.

  • DragEnter - occurs when an object is dragged into the drop target's boundary.
  • DragLeave - occurs when an object is dragged out of the drop target's boundary.
  • Drop - occurs when an object is dropped on the drop target.

Properties:

  • DragOverShape - of type IDragDropAware which gets the item that the user has dragged over.
  • DraggingModels - of type IEnumerable and gets the items that are being dragged.
  • IsDragging - boolean flag indicating if a dragging operation is being currently executed.

Methods:

  • InitializeDrag - this method accepts a point as parameter and prepares a drag operation from that point.
  • StartDrag - a boolean method which starts a drag operation and invokes the StartDragging event. Returns true if a drag can begin and false if the Dragging event has not being handled.
  • Drag - triggers the actual dragging logic and invokes the Dragging, DragEnter or DragLeave events.
  • CompleteDrag - invokes the Drop and CompleteDragging events.
  • CanDrag - a boolean method determing if a drag operation is possible. By default a drag is possible when the item is dragged further then the DiagramConstants.StartDragDelta constant.

GroupService

This service manages the grouping and ungrouping of items. More information about the RadDiagram grouping feature you can find in the Grouping tutorial.

The GroupService implements the IGroupService interface and it provides the GroupsChanged event. The event occurs when a root level logical group is created or destroyed through a new group or ungroup operation.

HitTestService

This service handles the hit-testing of diagram elements. It implements the IHitTestService interface and exposes the following members:

Properties:

  • ShapeUnderMouse - gets the shape that is currently under the mouse.
  • ItemUnderMouse - gets the item that is currently under the mouse.

Methods:

  • GetTopShapesUnderPoint - accepts a point as a parameter and returns the shape/s with the highest ZIndex under that point.
  • GetShapesNearPoint - accepts a point and a delta of type double as a parameter and returns the nearest shape/s within that delta.
  • GetItemsNearPoint - accepts a point and a delta of type double as a parameter and returns the nearest item/s within that delta.
  • GetTopItemNearPoint - accepts a point a and a delta of type double as a parameter and returns the item with the highest ZIndex within that delta.
  • GetShapesUnderRect - accepts a Rect as a paramater and returns the shapes under that rectangle.
  • GetConnectionsUnderRect - accepts a Rect as a parameter and returns the connections intersecting that rectangle.
  • GetItemsUnderRect - accepts a Rect as a parameter and returns the items under that rectangle.

ManipulationPointService

This service packages the undoable actions performed by the ConnectionTool and the ConnectionManipulationTool on a connection. It keeps a reference to the ConnectionEditorPoint which is being manipulated and which acts as a key binding element between the RadDiagramConnection, the ConnectionManipulationAdorner and the tools.

ResizingService

The ResizingService handles the scaling or resizing of diagram items. The service implements the IResizingService interface and exposes the following events:

  • StartResizing - this event occurs when a resize operation is about to begin. The event provides a CancelingManipulationEventArgs argument, which you can use to cancel the operation based on custom logic.

  • Resizing - this event occurs during a resize operation. It has an argument of type ResizingEventArgs which provides information about the new bounds of the DiagramItem that is being resized.

  • CompleteResizing - this event occurs when a resize operation has ended. It has an argument of type ResizingEventArgs which provides information about the new bounds of the DiagramItem that is being resized.

RotationService

The RotationService handles the rotation of one or more DiagramItems. The service implements the IRotationService interface and provides the following events:

  • StartRotating - this event occurs when a rotation is about to begin. The event provides an argument of type CancelingManipulationEventArgs, which you can use to cancel the operation based on custom logic.

  • Rotating - this event occurs during a rotation operation. It has an argument of type RotatingEventArgs which provides both the new and old value of the rotation angle.

  • CompleteRotating - this event occurs when a rotation is over. It has an argument of type RotatingEventArgs which provides both the new and old value of the rotation angle.

SegmentationService

The SegmentationService is responsible for the logical segmentation of the Diagram. This allows for iterating over only a portion of the "nearby" shapes in some scenarios instead of over the entire collection. The service implements the ISegmentationService interface the following members:

Properties:

  • IsSegmentationEnabled: Gets a value indicating whether segmentation enabled.

Methods:

  • void MapShapes(IEnumerable shapes): Maps the collection of shapes to different segments.
  • void MapShape(IShape shape): Maps the shape to its corresponding segment.
  • void MapShape(IShape shape, Rect bounds): Maps the shape according to the passed bounds.
  • void UnmapShape(IShape shape);: Unmap the passed shape from the saved segments.
  • IEnumerable GetShapes(Point point, double delta);: Get the shapes around a Point.
  • IEnumerable GetShapes(Rect rect);: Get the shapes inside a Rectangle.

SelectionService

The SelectionService manages the selection of RadDiagramItems. It implements the ISelectionService interface and provides the following events:

  • PreviewSelectionChanged - this event occurs before changing the selection in a RadDiagram instance. It provides an argument of type DiagramSelectionChangedEventArgs, which holds the collection of previously selected items as well the new selection. This argument has a Handled property, which can be set to True to cancel the selection.

  • SelectionChanged - this event occurs when a new selection is performed in a RadDiagram. Its DiagramSelectionChangedEventArgs argument provides access to the newly selected and the previously selected DiagramItems.

You can also use this service to get:

  • the currently selected diagram items through the SelectedItems property.

  • the currently selected shapes through the SelectedShapes property.

  • the currently selected connections through the SelectedConnections property.

SerializationService

The SerializationService manages the serialization and deserialization of items. It implements the ISerializationService interface and exposes the following events:

  • ItemSerializing - this event occurs when a RadDiagramItem is getting serialized.

  • ItemDeserializing - this event occurs when a RadDiagramItem is being deserialized.

Please have in mind that the RadDiagram uses a separate instance of the SerializationService, while external components, such as the RadDiagramToolbox use the default instance of the service. This is why, if you use the RadDiagram.ServiceLocator to get the default instance of the service and attach event handlers for the above events, you'll notice that they are only executed when external component serialize or deserialize RadDiagramItems. And if you want to handle the diagram internal serialization, it is better to use the RadDiagram serialization events.

SnappingService

The SnappingService manages the Diagramming Framework snapping. It implements the ISnappingService interface and exposes the SnappingLinesCalculated event. The event provides an argument of type SnappingLinesCalculatedEventArgs which holds the collections of vertical and horizontal snapping lines.

The SnappingService internally uses a SnappingEngine to handle the snap operations. You can find more information about the engine in the Align and Snap article.

ToolService

The ToolService manages the tools which react to a particular user action. It doesn't activate the tools but rather holds the instances of all diagramming tools and manages their actions accordingly. The service implements the IToolService interface and provides access to the currently active tool as well as to the primary tool in a RadDiagram. The service also provides the following list of Boolean properties:

  • IsControlDown - gets or sets whether the control-key is pressed.

  • IsAltDown - gets or sets whether the alt-key is pressed.

  • IsMouseDown - gets or sets whether the left mouse button is pressed.

You can also use an instance of this service to activate or deactivate a given Diagramming tool:

  • ActivateTool - this method takes a tool instance as an argument and activates it

  • DeactivateTool - this method takes a tool instance as an argument and deactivates it

UndoRedoService

The UndoRedoService manages the UndoRedo stack of undoable actions and commands. It implements the IUndoRedoService interface and provides:

  • UndoStack - this property holds the stack of undone actions

  • RedoStack - this property holds the stack of redone actions

  • IsActive- this is a Boolean property which determines whether the undoRedo service is executing undo or redo action at the moment.

  • RedoBufferSize - this property gets or sets the size of the RedoStack.

  • UndoBufferSize - this property gets or sets the size of the UndoStack.

The service also exposes an ActionExecuted event that occurs when either a do or an undo command is executed.

VirtualizationService

The VirtualizationService manages the virtualization of the diagramming items. It implements the IVirtualizationService interface and exposes the following virtual methods, which can get overridden in order to customize the behavior of the service:

  • Realize - this method realizes the items contained in provided bounds and virtualizes the others.

  • Virtualize - this method virtualizes a list of specified items.

In this article