Send comments on this topic. | Back to Introduction - All Topics | Help Version 16.5.9.25
Implementing User-Defined Objects With LEADTOOLS WPF Annotations

You can easily create your own annotation objects with LEADTOOLS Annotations framework. This tutorial shows you how to create two new annotations objects and how to write the required designer for them to plug these objects into the LEADTOOLS Annotations Automation framework.

Start by creating a new Windows Application (WPF) project.

Add references to the following DLL's:

  • Leadtools.Windows.Controls.dll
  • Leadtools.Windows.Annotations.dll

The object we are going to create is a simple object, a triangle. This object will have three points for the end points of the triangle and it will use a stroke for the triangle edges and a fill for the interior.

Add a new class to your project and name this class MyTriangleObject. Use the following source code for this class:

[Visual Basic]

[C#]

This is enough to manually add, remove, load, save and draw this object to an annotation container. However, we want to be able to draw and edit this object using The WPF annotation designers. Since we cannot find a suitable draw and edit designer to use with this class, we need to create our own.

First, create the draw designer. To do so, add a new class to your project and name this class "MyTriangleObjectDrawDesigner" and add the following code:

[Visual Basic]

	
Imports Leadtools.Windows.Annotations
'
' MyTriangleObject draw designer
' Will require the user to click 3 times once for each point
'
Public Class MyTriangleObjectDrawDesigner
   Inherits AnnDrawDesigner    ' must derive from AnnDrawDesigner or one of its derived classes
   ' private variables
   '
   ' we need to keep track on next point to add
   Private _clickCount As Integer
  '
   ' constructor
   '
   Public Sub New(ByVal container As AnnContainer)
      MyBase.New(container)
      _clickCount = 0
   End Sub
   '
  ' AnnDrawDesigner overrides
   '
   Protected Overrides Sub OnMouseLeftButtonDown(ByVal e As MouseButtonEventArgs)
      Dim handled As Boolean = False
      ' check we have started drawing. If not, the DrawObject will be null
     If (DrawObject Is Nothing) Then
         ' yes, create a new MyTriangleObject from ObjectTemplate
         Dim obj As MyTriangleObject = DirectCast(ObjectTemplate.Clone(), MyTriangleObject)
         ' set up the points
         Dim pt As Point = e.GetPosition(Me.Container)
         obj.FirstPoint = pt
        obj.SecondPoint = pt
         obj.ThirdPoint = pt
         ' start drawing this new object
        StartWorking(obj)
         handled = True
         ' we processed first click
         _clickCount += 1
      Else
         ' an object is already being drawn, so process the next click
         ' get our object and assign the next point to it
         Dim obj As MyTriangleObject = DirectCast(Me.DrawObject, MyTriangleObject)
        Dim pt As Point = e.GetPosition(Me.Container)
         If (_clickCount = 1) Then
            ' second point
            obj.SecondPoint = pt
            _clickCount += 1
            handled = True
         ElseIf (_clickCount = 2) Then
            ' third point
            obj.ThirdPoint = pt
            ' we are done!
            EndWorking()
           handled = True
         End If
      End If
      e.Handled = handled
   End Sub
   Protected Overrides Sub OnMouseRightButtonDown(ByVal e As MouseButtonEventArgs)
      ' we want to cancel the drawing if any other button has been clicked
     If (Not DrawObject Is Nothing) Then
         Cancel()
         e.Handled = True
      End If
   End Sub
   Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)
      Dim handled As Boolean = False
      ' check whether we are already drawing an object
      If (Not Me.DrawObject Is Nothing) Then
         ' yes, get this object and assign the next point first
        ' get out object and assign the point
         Dim obj As MyTriangleObject = DirectCast(DrawObject, MyTriangleObject)
         Dim pt As Point = e.GetPosition(Me.Container)
        If (_clickCount = 1) Then
            obj.SecondPoint = pt
         ElseIf (_clickCount = 2) Then
            obj.ThirdPoint = pt
         End If
         ' continue drawing this object
         Working()
         handled = True
      End If
      e.Handled = handled
   End Sub
   Protected Overrides Sub OnMouseLeftButtonUp(ByVal e As MouseButtonEventArgs)
      ' we do not need to do anything special on mouse up.
      ' so just see if we are drawing to return true (we handled it)
      Dim handled As Boolean = False
      If (DrawObject Is Nothing) Then
         handled = True
         e.Handled = handled
      End If
   End Sub
End Class

[C#]

	
using System;
using System.Text;
using System.Windows;
using System.Windows.Input;
using Leadtools.Windows.Annotations;
namespace Implementing_User_Defined_Objects_With_LEADTOOLS_Annotations
{
   //
   // MyTriangleObject draw designer
   // Will require the user to click 3 times, once for each point
   //
   public class MyTriangleObjectDrawDesigner :
      AnnDrawDesigner    // must derive from AnnDrawDesigner or one of its derived classes
   {
      // private variables
      //
      // we need to keep track of the next point to add
      private int _clickCount;
      //
      // constructor
      //
      public MyTriangleObjectDrawDesigner(AnnContainer container)
         : base(container)
      {
         _clickCount = 0;
      }
      //
      // AnnDrawDesigner overrides
      //
      protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
      {
         bool handled = false;
         // check whether we have started drawing. If not, the DrawObject will be null
         if(DrawObject == null)
         {
            // yes, create a new MyTriangleObject from ObjectTemplate
            MyTriangleObject obj = ObjectTemplate.Clone() as MyTriangleObject;
            // set up the points
            Point pt = e.GetPosition(this.Container);
            obj.FirstPoint = pt;
            obj.SecondPoint = pt;
            obj.ThirdPoint = pt;
            // start drawing this new object
            StartWorking(obj);
            handled = true;
            // we processed the first click
            _clickCount++;
         }
         else
         {
            // an object is already being drawn, so process the next click
            // get our object and assign the next point to it
            MyTriangleObject obj = this.DrawObject as MyTriangleObject;
            Point pt = e.GetPosition(this.Container);
            if(_clickCount == 1)
            {
               // second point
               obj.SecondPoint = pt;
               _clickCount++;
               handled = true;
            }
            else if(_clickCount == 2)
            {
               // third point
               obj.ThirdPoint = pt;
               // we are done!
               EndWorking();
               handled = true;
            }
         }
         e.Handled = handled;
      }
      protected override void OnMouseRightButtonDown(MouseButtonEventArgs e)
      {
         // we want to cancel the drawing if any other button has been clicked
         if(DrawObject != null)
         {
            Cancel();
            e.Handled = true;
         }
      }
      protected override void OnMouseMove(MouseEventArgs e)
      {
         bool handled = false;
         // check whether we are already drawing an object
         if(this.DrawObject != null)
         {
            // yes, get this object and assign the next point first
            // get out object and assign the point
            MyTriangleObject obj = DrawObject as MyTriangleObject;
            Point pt = e.GetPosition(this.Container);
            if(_clickCount == 1)
               obj.SecondPoint = pt;
            else if(_clickCount == 2)
               obj.ThirdPoint = pt;
            // continue drawing this object
            Working();
            handled = true;
        }
        e.Handled = handled;
     }
     protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
     {
        // we do not need to do anything special on mouse up.
        // so just see if we are drawing to return true (we handled it)
        bool handled = false;
        if(DrawObject == null)
           handled = true;
        e.Handled = handled;
     }
   }
}

Next create the edit designer. To do so, add a new class to your project and name this class "MyTriangleObjectEditDesigner" and add the following code:

[Visual Basic]

	
Imports Leadtools.Windows.Annotations
'
' MyTriangleObject edit designer
' The user can click on any of the points and move them around, as well as clicking and dragging the object itself.
'
Public Class MyTriangleObjectEditDesigner
   Inherits AnnEditDesigner    ' must derive from AnnEditDesigner or one of its derived classes
   '
  ' constructor
   '
   Public Sub New(ByVal triangleObj As MyTriangleObject)
      MyBase.New(triangleObj)
   End Sub
   '
   ' AnnEditDesigner overrides
   '
   Public Overrides ReadOnly Property ControlPointCount() As Integer
      Get
         ' return the number of control points we need
         ' in this case 3, one for each point in our triangle
         Return 3
      End Get
   End Property
   Public Overrides Function GetControlPointsLocation() As Point()
      ' return the position of these control points
      ' in this case, same as the points from our object
      Dim obj As MyTriangleObject = DirectCast(AdornedElement, MyTriangleObject)
      Return New Point() _
      { _
         obj.FirstPoint, _
         obj.SecondPoint, _
         obj.ThirdPoint _
      }
  End Function
   Protected Overrides Sub MoveControlPoint(ByVal controlPointIndex As Integer, ByVal pt As Point)
      ' user has clicked and moved a point.
      ' based on the index, we can tell if the user dragged the first, second or third point
      Dim obj As MyTriangleObject = DirectCast(AdornedElement, MyTriangleObject)
      Select Case (controlPointIndex)
         Case 0
            ' first point
            obj.FirstPoint = pt
         Case 1
            ' second point
            obj.SecondPoint = pt
         Case 2
            ' third point
            obj.ThirdPoint = pt
      End Select
   End Sub
   ' Note, we will not override Move or MoveHeader since the default implementation is good enough for our object
End Class

[C#]

	
using System;
using System.Text;
using System.Windows;
using Leadtools.Windows.Annotations;
namespace Implementing_User_Defined_Objects_With_LEADTOOLS_Annotations
{
   //
   // MyTriangleObject edit designer
   // The user can click on any of the points and move them around, as well as clicking and dragging the object itself.
   //
   public class MyTriangleObjectEditDesigner :
      AnnEditDesigner    // must derive from AnnEditDesigner or one of its derived classes
   {
      //
      // constructor
      //
      public MyTriangleObjectEditDesigner(MyTriangleObject triangleObj)
         : base(triangleObj)
      {
      }
      //
      // AnnEditDesigner overrides
      //
      public override int ControlPointCount
      {
         get
         {
            // return the number of control points we need
            // in this case 3, one for each point in our triangle
            return 3;
         }
      }
      public override Point[] GetControlPointsLocation()
      {
         // return the position of these control points
         // in this case, same as the points from our object
         MyTriangleObject obj = AdornedElement as MyTriangleObject;
         return new Point[]
          {
             obj.FirstPoint,
             obj.SecondPoint,
             obj.ThirdPoint
          };
      }
      protected override void MoveControlPoint(int controlPointIndex, Point pt)
      {
         // user has clicked and moved a point.
         // based on the index, we can tell if the user dragged the first, second or third point
         MyTriangleObject obj = AdornedElement as MyTriangleObject;
         switch(controlPointIndex)
         {
            case 0:
               // first point
               obj.FirstPoint = pt;
               break;
            case 1:
               // second point
               obj.SecondPoint = pt;
               break;
            case 2:
               // third point
               obj.ThirdPoint = pt;
               break;
         }
      }
      // Note, we will not override Move or MoveHeader since the default implementation is good enough for our object
   }
}

Now let us test these new objects. Open Window1.xaml file and replace it by the following:.

[Visual Basic]

[C#]

Switch to Window1 code view (for VB project right-click Window1 in the solution explorer then select View Code and for C# project open Window1.xaml.cs file) and add the following lines at the beginning of the file:

[Visual Basic]
	
Imports Leadtools.Windows.Annotations
[C#]
	
using Leadtools.Windows.Annotations;

Declare the following private variables:

[Visual Basic]
	
Private theManager As AnnAutomationManager
Private theAutomation As AnnAutomation
[C#]
	
private AnnAutomationManager theManager;
private AnnAutomation theAutomation;

Add the following functions code to class Window1:

[Visual Basic]

[C#]

Build and run the application to test it.