Error processing SSI file
LEADTOOLS Annotations (Deprecated)

Show in webframe

You can easily create your own annotation objects with LEADTOOLS Annotations framework. This secion 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:

  1. Start by creating a new Windows Application project.
  2. Add references to the following DLL's:
    • Leadtools.dll
    • Leadtools.WinForms.dll
    • Leadtools.Codecs.dll
    • Leadtools.Annotations.dll
  3. The first object we are going to create is a simple triangle object. This object will have three points for the end points of the triangle and it will support a pen to stroke the triangle edges and a brush to fill the interior.

    Add a new class to your project, name this class MyTriangleObject. Following is the source code for this class:

    [Visual Basic]

                Imports System
                Imports System.Drawing
                Imports System.Drawing.Drawing2D
                Imports System.Runtime.Serialization
                Imports Leadtools.Annotations
                '
                ' Triangle annotation object class
                ' This class will have a 3 points for a triangle objects that can be stroked with a pen and filled with a brush
                '
                ' our class must be serializable to play well with the annotation load/save and undo/redo features
                <Serializable()> _
                Public Class MyTriangleObject
                   Inherits AnnObject    ' must derive from AnnObject or one of its derived classes
                   '
                   ' our private variables
                   '
                   ' the three points that define our triangle
                   <NonSerialized()> Private _firstPoint As AnnPoint
                   <NonSerialized()> Private _secondPoint As AnnPoint
                   <NonSerialized()> Private _thirdPoint As AnnPoint
                   '
                   ' constructor
                   '
                   Public Sub New()
                      ' supportsPen = yes, supportsBrush = yes, supportsFont = no
                      MyBase.New( _
                         True, _
                         True, _
                         False)
                      ' initialize the points
                      _firstPoint = AnnPoint.Empty
                      _secondPoint = AnnPoint.Empty
                      _thirdPoint = AnnPoint.Empty
                   End Sub
                   '
                   ' ISerializable implementation
                   '
                   Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
                      MyBase.New(info, context)    ' do not forget to call the base class version
                      ' we need to deserialize our private variables here
                      _firstPoint = DirectCast(info.GetValue("FirstPointName", GetType(AnnPoint)), AnnPoint)
                      _secondPoint = DirectCast(info.GetValue("SecondPointName", GetType(AnnPoint)), AnnPoint)
                      _thirdPoint = DirectCast(info.GetValue("ThirdPointName", GetType(AnnPoint)), AnnPoint)
                   End Sub
                   Public Overrides Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext)
                      ' we need to serialize our private variables here
                      ' call the base class version
                      MyBase.GetObjectData(info, context)
                      ' serialize the points
                      info.AddValue("FirstPointName", _firstPoint, GetType(AnnPoint))
                      info.AddValue("SecondPointName", _secondPoint, GetType(AnnPoint))
                      info.AddValue("ThirdPointName", _thirdPoint, GetType(AnnPoint))
                   End Sub
                   '
                   ' accessors to the points
                   '
                   Public Property FirstPoint() As AnnPoint
                      Get
                         Return _firstPoint
                      End Get
                      Set(ByVal Value As AnnPoint)
                         _firstPoint = Value
                      End Set
                   End Property
                   Public Property SecondPoint() As AnnPoint
                      Get
                         Return _secondPoint
                      End Get
                      Set(ByVal Value As AnnPoint)
                         _secondPoint = Value
                      End Set
                   End Property
                   Public Property ThirdPoint() As AnnPoint
                      Get
                         Return _thirdPoint
                      End Get
                         Set(ByVal Value As AnnPoint)
                         _thirdPoint = Value
                      End Set
                   End Property
                   '
                   ' AnnObject overrides
                   '
                   Protected Overrides Function Create() As AnnObject
                      ' must return a new instance of our class
                      Return New MyTriangleObject
                   End Function
                   Public Overrides Function Clone() As Object
                      ' override the clone method
                      ' first call the base implementation
                      Dim obj As MyTriangleObject = DirectCast(MyBase.Clone(), MyTriangleObject)
                      ' next, copy the points
                      obj.FirstPoint = FirstPoint
                      obj.SecondPoint = SecondPoint
                      obj.ThirdPoint = ThirdPoint
                      Return obj
                   End Function
                   Public Overrides Function GetGraphicsPath(ByVal mode As AnnGetGraphicsPathMode) As GraphicsPath
                      ' must a return a graphics path representation of our object
                      ' Note: this object does not require us to override AnnObject.DrawObject since we can
                      ' use a graphics path to represents the object completely.
                      ' create a new graphics path
                      Dim path As New GraphicsPath
                      ' add the triangle points as a series of lines
                      ' convert the points to pixels PointF
                      Dim pts() As PointF = _
                      { _
                         FirstPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF(), _
                         SecondPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF(), _
                         ThirdPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF() _
                      }
                      path.AddLines(pts)
                      path.CloseFigure()
                      Return path
                   End Function
                End Class
                
    

    [C#]

                using System;
                using System.Drawing;
                using System.Drawing.Drawing2D;
                using System.Runtime.Serialization;
                using Leadtools.Annotations;
                namespace MyNamespace
                {
                   //
                   // Triangle annotation object class
                   // This class will have a 3 points for a triangle objects that can be stroked with a pen and filled with a brush
                   //
                   [Serializable] // our class must be serializable to play well with the annotation load/save and undo/redo features
                   public class MyTriangleObject:
                      AnnObject    // must derive from AnnObject or one of its derived classes
                   {
                      //
                      // our private variables
                      //
                      // the three points that define our triangle
                      [NonSerialized()] private AnnPoint _firstPoint;
                      [NonSerialized()] private AnnPoint _secondPoint;
                      [NonSerialized()] private AnnPoint _thirdPoint;
                      //
                      // constructor
                      //
                      public MyTriangleObject() :
                         base(
                         true,    // yes, we require a pen
                         true,    // yes, we require a brush
                         false)    // no, we do not require a font
                      {
                         // initialize the points
                         _firstPoint = AnnPoint.Empty;
                         _secondPoint = AnnPoint.Empty;
                         _thirdPoint = AnnPoint.Empty;
                      }
                      //
                      // ISerializable implementation
                      //
                      protected MyTriangleObject(SerializationInfo info, StreamingContext context) :
                         base(info, context)    // do not forget to call the base class version
                      {
                         // we need to deserialize our private variables here
                         _firstPoint = (AnnPoint)info.GetValue("FirstPointName", typeof(AnnPoint));
                         _secondPoint = (AnnPoint)info.GetValue("SecondPointName", typeof(AnnPoint));
                         _thirdPoint = (AnnPoint)info.GetValue("ThirdPointName", typeof(AnnPoint));
                      }
                      public override void GetObjectData(SerializationInfo info, StreamingContext context)
                      {
                         // we need to serialize our private variables here
                         // call the base class version
                         base.GetObjectData(info, context);
                         // serialize the points
                         info.AddValue("FirstPointName", _firstPoint, typeof(AnnPoint));
                         info.AddValue("SecondPointName", _secondPoint, typeof(AnnPoint));
                         info.AddValue("ThirdPointName", _thirdPoint, typeof(AnnPoint));
                      }
                      //
                      // accessors to the points
                      //
                      public AnnPoint FirstPoint
                      {
                         get
                         {
                            return _firstPoint;
                         }
                         set
                         {
                            _firstPoint = value;
                         }
                      }
                      public AnnPoint SecondPoint
                      {
                         get
                         {
                            return _secondPoint;
                         }
                         set
                         {
                            _secondPoint = value;
                         }
                      }
                      public AnnPoint ThirdPoint
                      {
                         get
                         {
                            return _thirdPoint;
                         }
                         set
                         {
                            _thirdPoint = value;
                         }
                      }
                      //
                      // AnnObject overrides
                      //
                      protected override AnnObject Create()
                      {
                         // must return a new instance of our class
                         return new MyTriangleObject();
                      }
                      public override object Clone()
                      {
                         // override the clone method
                         // first call the base implementation
                         MyTriangleObject obj = base.Clone() as MyTriangleObject;
                         // next, copy the points
                         obj.FirstPoint = FirstPoint;
                         obj.SecondPoint = SecondPoint;
                         obj.ThirdPoint = ThirdPoint;
                         return obj;
                      }
                      public override GraphicsPath GetGraphicsPath(AnnGetGraphicsPathMode mode)
                      {
                         // must a return a graphics path representation of our object
                         // Note: this object does not require us to override AnnObject.DrawObject since we can
                         // use a graphics path to represent the object completely.
                         // create a new graphics path
                         GraphicsPath path = new GraphicsPath();
                         // add the triangle points as a series of lines
                         // convert the points to pixels PointF
                         PointF[] pts =
                         {
                            FirstPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF(),
                            SecondPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF(),
                            ThirdPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF()
                         };
                      path.AddLines(pts);
                      path.CloseFigure();
                      return path;
                      }
                   }
                }
                
    
    This 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 annotation designers. Since we cannot find a suitable draw and edit designer to use with this class, we need to create our own.
  4. First, the draw designer, add a new class to your project, name this class "MyTriangleObjectDrawDesigner" and add the following code:

    [Visual Basic]

                Imports System
                Imports System.Drawing
                Imports System.Windows.Forms
                Imports Leadtools.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()
                      _clickCount = 0
                   End Sub
                   '
                   ' AnnDrawDesigner overrides
                   '
                   Public Overrides Function MouseDown(ByVal e As MouseEventArgs) As Boolean
                      Dim handled As Boolean = False
                      ' only process left button clicks
                      If (e.Button = MouseButtons.Left) Then
                         ' check if we have not started drawing yet, DrawObject will be null
                         If (IsNothing(DrawObject)) Then
                            ' yes, create a new MyTriangleObject from ObjectTemplate
                            Dim obj As MyTriangleObject = DirectCast(ObjectTemplate.Clone(), MyTriangleObject)
                            ' setup the points
                            Dim pt As AnnPoint = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit)
                            obj.FirstPoint = pt
                            obj.SecondPoint = pt
                            obj.ThirdPoint = pt
                            ' start drawing this new object
                            StartWorking(obj)
                            handled = True
                            ' we processed first click
                            _clickCount = _clickCount + 1
                         Else
                            ' an object is already being drawn, so process next click
                            ' get our object and assign next point to it
                            Dim obj As MyTriangleObject = DirectCast(DrawObject, MyTriangleObject)
                            Dim pt As AnnPoint = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit)
                            If (_clickCount = 1) Then
                               ' second point
                               obj.SecondPoint = pt
                               _clickCount = _clickCount + 1
                            ElseIf (_clickCount = 2) Then
                               ' third point
                               obj.ThirdPoint = pt
                               ' we are done!
                               EndWorking()
                            End If
                         End If
                      Else
                         ' we want to cancel the drawing if any other button has been clicked
                         If (Not IsNothing(DrawObject)) Then
                            Cancel()
                            handled = True
                         End If
                      End If
                      Return handled
                   End Function
                   Public Overrides Function MouseMove(ByVal e As MouseEventArgs) As Boolean
                      Dim handled As Boolean = False
                      ' check if we are already drawing an object
                      If (Not IsNothing(DrawObject)) Then
                         ' yes, get this object and assign the next point
                         ' first, save the old invalid rectangle
                         Dim rcOld As Rectangle = DrawObject.InvalidRectangle
                         ' get out object and assign the point
                         Dim obj As MyTriangleObject = DirectCast(DrawObject, MyTriangleObject)
                         Dim pt As AnnPoint = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit)
                         If (_clickCount = 1) Then
                            obj.SecondPoint = pt
                         ElseIf (_clickCount = 2) Then
                            obj.ThirdPoint = pt
                         End If
                         ' get the new invalid rectangle
                         Dim rcNew As Rectangle = DrawObject.InvalidRectangle
                         ' continue drawing this object
                         Working(Rectangle.Union(rcOld, rcNew))
                         handled = True
                      End If
                      Return handled
                   End Function
                   Public Overrides Function MouseUp(ByVal e As MouseEventArgs) As Boolean
                      ' 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 (IsNothing(DrawObject)) Then
                         handled = True
                      End If
                      Return handled
                   End Function
                End Class
                
    

    [C#]

                using System;
                using System.Drawing;
                using System.Windows.Forms;
                using Leadtools.Annotations;
                namespace MyNamespace
                {
                   //
                   // 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 on next point to add
                      private int _clickCount;
                      //
                      // constructor
                      //
                      public MyTriangleObjectDrawDesigner()
                      {
                            _clickCount = 0;
                      }
                      //
                      // AnnDrawDesigner overrides
                      //
                      public override bool MouseDown(MouseEventArgs e)
                      {
                         bool handled = false;
                         // only process left button clicks
                         if(e.Button == MouseButtons.Left)
                         {
                            // check if we have not started drawing yet, DrawObject will be null
                            if(DrawObject == null)
                            {
                               // yes, create a new MyTriangleObject from ObjectTemplate
                               MyTriangleObject obj = ObjectTemplate.Clone() as MyTriangleObject;
                               // setup the points
                               AnnPoint pt = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit);
                               obj.FirstPoint = pt;
                               obj.SecondPoint = pt;
                               obj.ThirdPoint = pt;
                               // start drawing this new object
                               StartWorking(obj);
                               handled = true;
                               // we processed first click
                               _clickCount++;
                            }
                            else
                            {
                               // an object is already being drawn, so process next click
                               // get our object and assign next point to it
                               MyTriangleObject obj = DrawObject as MyTriangleObject;
                               AnnPoint pt = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit);
                               if(_clickCount == 1)
                               {
                                  // second point
                                  obj.SecondPoint = pt;
                                  _clickCount++;
                               }
                               else if(_clickCount == 2)
                               {
                                  // third point
                                  obj.ThirdPoint = pt;
                                  // we are done!
                                  EndWorking();
                               }
                            }
                         }
                         else
                         {
                            // we want to cancel the drawing if any other button has been clicked
                            if(DrawObject != null)
                            {
                               Cancel();
                               handled = true;
                            }
                         }
                         return handled;
                      }
                      public override bool MouseMove(MouseEventArgs e)
                      {
                         bool handled = false;
                         // check if we are already drawing an object
                         if(DrawObject != null)
                         {
                            // yes, get this object and assign the next point
                            // first, save the old invalid rectangle
                            Rectangle rcOld = DrawObject.InvalidRectangle;
                            // get out object and assign the point
                            MyTriangleObject obj = DrawObject as MyTriangleObject;
                            AnnPoint pt = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit);
                            if(_clickCount == 1)
                               obj.SecondPoint = pt;
                            else if(_clickCount == 2)
                               obj.ThirdPoint = pt;
                            // get the new invalid rectangle
                            Rectangle rcNew = DrawObject.InvalidRectangle;
                            // continue drawing this object
                            Working(Rectangle.Union(rcOld, rcNew));
                            handled = true;
                         }
                         return handled;
                      }
                      public override bool MouseUp(MouseEventArgs 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;
                         return handled;
                      }
                   }
                }
                
    
  5. Next, the edit designer, add a new class to your project, name this class "MyTriangleObjectEditDesigner" and add the following code:

    [Visual Basic]

                Imports System
                Imports System.Drawing
                Imports Leadtools.Annotations
                '
                ' MyTriangleObject edit designer
                ' 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()
                   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 AnnPoint()
                      ' return the position of these control points
                      ' in this case, same as the points from our object
                      Dim obj As MyTriangleObject = DirectCast(EditObject, MyTriangleObject)
                      Return New AnnPoint() _
                      { _
                         obj.FirstPoint, _
                         obj.SecondPoint, _
                         obj.ThirdPoint() _
                      }
                   End Property
                   Protected Overrides Sub MoveControlPoint(ByVal controlPointIndex As Integer, ByVal pt As AnnPoint)
                      ' 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(EditObject, MyTriangleObject)
                      Select Case (controlPointIndex)
                         Case 0
                            ' first point
                            obj.FirstPoint = pt.ConvertTo(Container.UnitConverter, obj.FirstPoint.Unit)
                         Case 1
                            ' second point
                            obj.SecondPoint = pt.ConvertTo(Container.UnitConverter, obj.SecondPoint.Unit)
                         Case 2
                            ' third point
                            obj.ThirdPoint = pt.ConvertTo(Container.UnitConverter, obj.ThirdPoint.Unit)
                      End Select
                   End Sub
                   ' Note, we will not override Move or MoveName since the default implementation is good enough for our object
                End Class
                
    

    [C#]

                using System;
                using System.Drawing;
                using Leadtools.Annotations;
                namespace MyNamespace
                {
                   //
                   // 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()
                      {
                      }
                      //
                      // 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 AnnPoint[] GetControlPointsLocation()
                      {
                         // return the position of these control points
                         // in this case, same as the points from our object
                         MyTriangleObject obj = EditObject as MyTriangleObject;
                         return new AnnPoint[]
                         {
                            obj.FirstPoint,
                            obj.SecondPoint,
                            obj.ThirdPoint
                         };
                      }
                      protected override void MoveControlPoint(int controlPointIndex, AnnPoint 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 = EditObject as MyTriangleObject;
                         switch(controlPointIndex)
                         {
                            case 0:
                               // first point
                               obj.FirstPoint = pt.ConvertTo(Container.UnitConverter, obj.FirstPoint.Unit);
                               break;
                            case 1:
                               // second point
                               obj.SecondPoint = pt.ConvertTo(Container.UnitConverter, obj.SecondPoint.Unit);
                               break;
                            case 2:
                               // third point
                               obj.ThirdPoint = pt.ConvertTo(Container.UnitConverter, obj.ThirdPoint.Unit);
                               break;
                         }
                      }
                      // Note, we will not override Move or MoveName since the default implementation is good enough for our object
                   }
                }
                
    
    Now we are going to add another object. The CheckBox class will use the ControlPaint class to draw a check box along with a text string. Our class will not support a pen, but a brush and a text. We will use the AnnTextObject as the base class for our CheckBox class.
  6. Start by adding a new class to your project, name this class MyCheckBoxObject. The following is the source code for this class:

    [Visual Basic]

                Imports System
                Imports System.Drawing
                Imports System.Drawing.Drawing2D
                Imports System.Windows.Forms
                Imports System.Runtime.Serialization
                Imports Leadtools.Annotations
                '
                ' CheckBox annotation object class
                ' our class will use the ControlPaint class to draw a check box along with text.
                ' our class will not support a pen, but a brush and a text
                '
                ' our class must be serializable to play well with the annotation load/save and undo/redo features
                <Serializable()> _
                Public Class MyCheckBoxObject
                   Inherits AnnTextObject    ' We will derive from AnnTextObject so we already have the text
                   '
                   ' our private variables
                   '
                   ' the checkbox state
                   <NonSerialized()> Private _checked As Boolean
                   '
                   ' constructor
                   '
                   Public Sub New()
                      ' supportsPen = no, supportsBrush = yes, supportsFont = yes
                      MyBase.New( _
                         False, _
                         True, _
                         True)
                      ' initialize the state
                      _checked = False
                   End Sub
                   '
                   ' ISerializable implementation
                   '
                   Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
                      MyBase.New(info, context)    ' do not forget to call the base class version
                      ' we need to deserialize our private variables here
                      _checked = info.GetBoolean("Checked")
                   End Sub
                   Public Overrides Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext)
                      ' we need to serialize our private variables here
                      ' call the base class version
                      MyBase.GetObjectData(info, context)
                      ' serialize the state
                      info.AddValue("Checked", _checked)
                   End Sub
                   '
                   ' accessors
                   '
                   Public Property Checked() As Boolean
                      Get
                         Return _checked
                      End Get
                      Set(ByVal Value As Boolean)
                         _checked = Value
                      End Set
                   End Property
                   '
                   ' AnnObject overrides
                   '
                   Protected Overrides Function Create() As AnnObject
                      ' must return a new instance of our class
                      Return New MyCheckBoxObject
                   End Function
                   Public Overrides Function Clone() As Object
                      ' override the clone method
                      ' first call the base implementation
                      Dim obj As MyCheckBoxObject = DirectCast(MyBase.Clone(), MyCheckBoxObject)
                      Return obj
                   End Function
                   ' we will not override GetGraphicsPath, the base class version is
                   ' suitable for hittesting and finding the object bounding rectangle.
                   ' however, we will override DrawObject to manually paint the object
                   Protected Overrides Sub DrawObject(ByVal g As Graphics)
                      ' begin the drawing
                      Dim gState As GraphicsState = BeginDraw(g)
                      If (Not gState Is Nothing) Then
                         ' get the bounding rectangle in pixels
                         Dim boundsPixels As RectangleF = Bounds.ConvertTo(UnitConverter, AnnUnit.Pixel).ToRectangleF()
                         ' first, see if we have a brush, if so, fill this rectangle
                         If (HasBrush) Then
                            Dim br As Brush = Brush.Create(UnitConverter, Bounds)
                            g.FillRectangle(br, boundsPixels)
                            br.Dispose()
                         End If
                         If (IsNonEmptyRectangle(boundsPixels)) Then
                            ' use the ControlPaint class to paint the check box on the left of the object
                            Dim rc As Rectangle = Rectangle.Round(boundsPixels)
                            If (IsNonEmptyRectangle(rc)) Then
                               Dim checkBoxRectangle As New Rectangle(rc.Left, rc.Top, rc.Height, rc.Height)
                               If (Checked) Then
                                  ControlPaint.DrawCheckBox(g, checkBoxRectangle, ButtonState.Checked)
                               Else
                                  ControlPaint.DrawCheckBox(g, checkBoxRectangle, ButtonState.Normal)
                               End If
                               ' update the bounds rectangle
                               boundsPixels = RectangleF.FromLTRB(checkBoxRectangle.Right, checkBoxRectangle.Top, boundsPixels.Right, boundsPixels.Bottom)
                            End If
                         End If
                         ' get the edge margin in pixels
                         Dim edgeMarginPixels As Single = EdgeMargin.Converted(UnitConverter, AnnUnit.Pixel)
                         boundsPixels.Inflate(-edgeMarginPixels, -edgeMarginPixels)
                         ' finally draw the text
                         If (HasFont AndAlso Not IsNothing(Text) AndAlso Text <> String.Empty AndAlso Text.Length > 0 AndAlso IsNonEmptyRectangle(boundsPixels)) Then
                            Dim sf As StringFormat = DirectCast(StringFormat.GenericDefault.Clone(), StringFormat)
                            sf.Alignment = Alignment
                            sf.LineAlignment = LineAlignment
                            Dim fnt As Font = Font.Create(g, UnitConverter)
                            Dim br As New SolidBrush(TextColor)
                            g.DrawString(Text, fnt, br, boundsPixels, sf)
                            br.Dispose()
                            fnt.Dispose()
                            sf.Dispose()
                         End If
                         EndDraw(g, gState)
                      End If
                   End Sub
                  Shared Function FixRectangle(ByVal rc As RectangleF) As RectangleF
                     If (rc.Left > rc.Right OrElse rc.Top > rc.Bottom) Then
                        Return RectangleF.FromLTRB( _
                           Math.Min(rc.Left, rc.Right), _
                           Math.Min(rc.Top, rc.Bottom), _
                           Math.Max(rc.Left, rc.Right), _
                           Math.Max(rc.Top, rc.Bottom))
                     Else
                        Return rc
                     End If
                  End Function
                  Shared Function IsNonEmptyRectangle(ByVal rc As RectangleF) As Boolean
                     Return rc.Width <> 0 AndAlso rc.Height <> 0
                  End Function
                End Class
                
    

    [C#]

                using System;
                using System.Drawing;
                using System.Drawing.Drawing2D;
                using System.Windows.Forms;
                using System.Runtime.Serialization;
                using Leadtools.Annotations;
                namespace MyNamespace
                {
                   //
                   // CheckBox annotation object class
                   // our class will use the ControlPaint class to draw a check box along with text.
                   // our class will not support a pen, but a brush and a text
                   //
                   [Serializable] // our class must be serializable to play well with the annotation load/save and undo/redo features
                   public class MyCheckBoxObject :
                      AnnTextObject    // We will derive from AnnTextObject so we already have the text
                   {
                      //
                      // our private variables
                      //
                      // the checkbox state
                      [NonSerialized()] private bool _checked;
                      //
                      // constructor
                      //
                      public MyCheckBoxObject() :
                         base(
                         false,    // no, we do not require a pen
                         true,    // we require a brush
                         true)    // we require a font
                      {
                         // initialize the state
                         _checked = false;
                      }
                      //
                      // ISerializable implementation
                      //
                      protected MyCheckBoxObject(SerializationInfo info, StreamingContext context) :
                      base(info, context)    // do not forget to call the base class version
                      {
                         // we need to deserialize our private variables here
                         _checked = info.GetBoolean("Checked");
                      }
                      public override void GetObjectData(SerializationInfo info, StreamingContext context)
                      {
                         // we need to serialize our private variables here
                         // call the base class version
                         base.GetObjectData(info, context);
                         // serialize the state
                         info.AddValue("Checked", _checked);
                      }
                      //
                      // accessors
                      //
                      public bool Checked
                      {
                         get
                         {
                            return _checked;
                         }
                         set
                         {
                            _checked = value;
                         }
                      }
                      //
                      // AnnObject overrides
                      //
                      protected override AnnObject Create()
                      {
                         // must return a new instance of our class
                         return new MyCheckBoxObject();
                      }
                      public override object Clone()
                      {
                         // override the clone method
                         // first call the base implementation
                         MyCheckBoxObject obj = base.Clone() as MyCheckBoxObject;
                         return obj;
                      }
                      // we will not override GetGraphicsPath, the base class version is
                      // suitable for hittesting and finding the object bounding rectangle.
                      // however, we will override DrawObject to manually paint the object
                      protected override void DrawObject(Graphics g)
                      {
                         // begin the drawing
                         GraphicsState gState = BeginDraw(g);
                         if(gState != null)
                         {
                            // get the bounding rectangle in pixels
                            RectangleF boundsPixels = Bounds.ConvertTo(UnitConverter, AnnUnit.Pixel).ToRectangleF();
                            // first, see if we have a brush, if so, fill this rectangle
                            if(HasBrush)
                            {
                               using(Brush br = Brush.Create(UnitConverter, Bounds))
                               g.FillRectangle(br, boundsPixels);
                            }
                            if(IsNonEmptyRectangle(boundsPixels))
                            {
                               // use the ControlPaint class to paint the check box on the left of the object
                               Rectangle rc = Rectangle.Round(boundsPixels);
                               if(IsNonEmptyRectangle(rc))
                               {
                                  Rectangle checkBoxRectangle = new Rectangle(rc.Left, rc.Top, rc.Height, rc.Height);
                                  ControlPaint.DrawCheckBox(g, checkBoxRectangle, Checked ? ButtonState.Checked: ButtonState.Normal);
                                  // update the bounds rectangle
                                  boundsPixels = RectangleF.FromLTRB(checkBoxRectangle.Right, checkBoxRectangle.Top, boundsPixels.Right, boundsPixels.Bottom);
                               }
                            }
                            // get the edge margin in pixels
                            float edgeMarginPixels = EdgeMargin.Converted(UnitConverter, AnnUnit.Pixel);
                            boundsPixels.Inflate(-edgeMarginPixels, -edgeMarginPixels);
                            // finally draw the text
                            if(HasFont && Text != null && Text != string.Empty && Text.Length > 0 && IsNonEmptyRectangle(boundsPixels))
                            {
                               using(StringFormat sf = StringFormat.GenericDefault.Clone() as StringFormat)
                               {
                                  sf.Alignment = Alignment;
                                  sf.LineAlignment = LineAlignment;
                                  using(Font font = Font.Create(g, UnitConverter))
                                  {
                                     using(Brush brush = new SolidBrush(TextColor))
                                     g.DrawString(Text, font, brush, boundsPixels, sf);
                                  }
                               }
                            }
                            EndDraw(g, gState);
                         }
                      }
                      static RectangleF FixRectangle(RectangleF rc)
                      {
                         if(rc.Left > rc.Right || rc.Top > rc.Bottom)
                            return RectangleF.FromLTRB(
                               Math.Min(rc.Left, rc.Right),
                               Math.Min(rc.Top, rc.Bottom),
                               Math.Max(rc.Left, rc.Right),
                               Math.Max(rc.Top, rc.Bottom));
                         else
                            return rc;
                      }
                      static bool IsNonEmptyRectangle(RectangleF rc)
                      {
                         return rc.Width != 0 && rc.Height != 0;
                      }
                   }
                }
                
    
    We will use the AnnRectangleDrawDesigner and AnnRectangleEditDesigner to draw and edit this class. However, we will add a custom run designer to handle the runtime behavor of this class. At runtime, we want the user to be able to click the CheckBox class and change the checked state.
  7. Add a new class to your project, name this class "MyCheckBoxRunDesigner" and add the following code:

    [Visual Basic]

                Imports System
                Imports System.Drawing
                Imports System.Windows.Forms
                Imports Leadtools.Annotations
                '
                ' MyCheckBoxObject run designer
                ' When the user clicks the object, flip the Checked state
                '
                Public Class MyCheckBoxObjectRunDesigner
                   Inherits AnnRunDesigner    ' must derive from AnnRunDesigner or one of its derived classes
                   '
                   ' constructor
                   '
                   Public Sub New()
                   End Sub
                   '
                   ' AnnRunDesigner overrides
                   '
                   Protected Overrides Sub OnRun(ByVal e As AnnRunDesignerEventArgs)
                      ' OnRun gets called while the user is running the object
                      ' check the state
                      If (e.OperationStatus = AnnDesignerOperationStatus.End) Then
                         ' End is when the user clicks the object by default, flip the Checked state
                         Dim obj As MyCheckBoxObject = DirectCast(e.Object, MyCheckBoxObject)
                         obj.Checked = Not obj.Checked
                         ' repaint this object
                         Owner.Invalidate(obj.InvalidRectangle)
                         ' we chose to ignore the default run for this object
                         ' not setting e.Cancel to true will play the hyperlink
                         e.Cancel = True
                      End If
                      MyBase.OnRun(e)
                   End Sub
                End Class
                
    

    [C#]

                using System;
                using System.Drawing;
                using System.Windows.Forms;
                using Leadtools.Annotations;
                namespace MyNamespace
                {
                   //
                   // MyCheckBoxObject run designer
                   // When the user clicks the object, flip the Checked state
                   //
                   public class MyCheckBoxObjectRunDesigner :
                   AnnRunDesigner    // must derive from AnnRunDesigner or one of its derived classes
                   {
                      //
                      // constructor
                      //
                      public MyCheckBoxObjectRunDesigner()
                      {
                      }
                      //
                      // AnnRunDesigner overrides
                      //
                      protected override void OnRun(AnnRunDesignerEventArgs e)
                      {
                         // OnRun gets called while the user is running the object
                         // check the state
                         if(e.OperationStatus == AnnDesignerOperationStatus.End)
                         {
                            // End is when the user clicks the object by default, flip the Checked state
                            MyCheckBoxObject obj = e.Object as MyCheckBoxObject;
                            obj.Checked = !obj.Checked;
                            // repaint this object
                            Owner.Invalidate(obj.InvalidRectangle);
                            // we chose to ignore the default run for this object
                            // not setting e.Cancel to true will play the hyperlink
                            e.Cancel = true;
                         }
                         base.OnRun(e);
                      }
                   }
                }
                
    
  8. Now let us test these new objects. Add a new RasterImageViewer control to your main form along with four buttons (Text = "Save", "Load", "Clear" and "Run/Design".

    At the top of the Form1 class, add the following:

    [Visual Basic]

                Imports System.IO
                Imports Leadtools
                Imports Leadtools.Codecs
                Imports Leadtools.WinForms
                Imports Leadtools.Annotations
                
    

    [C#]

                using System.IO;
                using Leadtools;
                using Leadtools.Codecs;
                using Leadtools.WinForms;
                using Leadtools.Annotations;
                using MyNamespace;
                
    
  9. Add a new handler for Form1 Load event and add the following code:

    [Visual Basic]

                   /// Private theManager As AnnAutomationManager
                Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
                   ' load an image into the viewer
                   Dim codecs As New RasterCodecs
                   RasterImageViewer1.Image = codecs.Load("C:\Users\Public\Documents\LEADTOOLS Images\Sample1.cmp")
                   ' create and setup the automation manager
                   theManager = New AnnAutomationManager
                   ' Create the default (all) automation objects.
                   theManager.CreateDefaultObjects()
                   ' add our own Triangle and CheckBox as automation objects
                   AddMyTriangleAutomationObject(theManager)
                   AddMyCheckBoxAutomationObject(theManager)
                   ' create the toolbar and add it to the form
                   theManager.CreateToolBar()
                   Controls.Add(theManager.ToolBar)
                   theManager.ToolBar.BringToFront()
                   ' setup the automation (will create the container as well)
                   Dim automation As New AnnAutomation(theManager, RasterImageViewer1)
                   ' setup this automation as the active one
                   automation.Active = True
                End Sub
                Private Sub AddMyTriangleAutomationObject(ByVal manager As AnnAutomationManager)
                   Dim autObj As New AnnAutomationObject
                   ' setup the ID
                   autObj.Id = AnnAutomationManager.UserObjectId
                   ' give it a friendly name
                   autObj.Name = "Triangle"
                   ' setup the object template
                   ' this the object that will be used when drawing new MyTriangleObject.    so, setup the pen and brush as desired
                   Dim obj As New MyTriangleObject
                   obj.Pen = New AnnPen(Color.Blue, New AnnLength(2, AnnUnit.Pixel))
                   obj.Brush = New AnnSolidBrush(Color.Yellow)
                   autObj.Object = obj
                   ' setup the draw, edit and run designers type
                   autObj.DrawDesignerType = GetType(MyTriangleObjectDrawDesigner)
                   autObj.EditDesignerType = GetType(MyTriangleObjectEditDesigner)
                   ' we will use the default run designer for this object
                   autObj.RunDesignerType = GetType(AnnRunDesigner)
                   ' we need a toolbar image, so create one
                   Dim btmp As New Bitmap(16, 16)
                   Dim g As Graphics = Graphics.FromImage(btmp)
                   g.FillRectangle(Brushes.Magenta, 0, 0, 16, 16)
                   g.DrawLine(Pens.Black, 8, 2, 14, 14)
                   g.DrawLine(Pens.Black, 14, 14, 2, 14)
                   g.DrawLine(Pens.Black, 2, 14, 8, 2)
                   g.Dispose()
                   autObj.ToolBarImage = btmp
                   ' setup the toolbar button tooltip text
                   autObj.ToolBarToolTipText = "Triangle"
                   ' setup the cursor used when drawing this object
                   autObj.DrawCursor = Cursors.Cross
                   ' setup the context menu for this object
                   ' we will use the default context menu
                   autObj.ContextMenu = AnnAutomationManager.CreateDefaultObjectContextMenu(autObj.Id)
                   ' finally add this object to the automation objects of the manager
                   manager.Objects.Add(autObj)
                End Sub
                Private Sub AddMyCheckBoxAutomationObject(ByVal manager As AnnAutomationManager)
                   Dim autObj As New AnnAutomationObject
                   ' setup the ID
                   autObj.Id = AnnAutomationManager.UserObjectId + 1
                   ' give it a friendly name
                   autObj.Name = "CheckBox"
                   ' setup the object template
                   ' this the object that will be used when drawing new MyCheckBoxObject.    so, setup the brush, font and text
                   Dim obj As New MyCheckBoxObject
                   obj.Checked = False
                   obj.Brush = New AnnSolidBrush(SystemColors.Control)
                   obj.Text = "CheckBox"
                   obj.TextColor = SystemColors.ControlText
                   obj.Font = New AnnFont("Arial", New AnnLength(8, AnnUnit.Point), FontStyle.Regular)
                   obj.Alignment = StringAlignment.Near
                   obj.LineAlignment = StringAlignment.Center
                   autObj.Object = obj
                   ' setup the draw, edit and run designers type
                   ' note, MyCheckBoxObject will use the default rectangle draw and edit designers
                   autObj.DrawDesignerType = GetType(AnnRectangleDrawDesigner)
                   autObj.EditDesignerType = GetType(AnnRectangleEditDesigner)
                   ' use our run designer
                   autObj.RunDesignerType = GetType(MyCheckBoxObjectRunDesigner)
                   ' we need a toolbar image, so create one
                   Dim btmp As New Bitmap(16, 16)
                   Dim g As Graphics = Graphics.FromImage(btmp)
                   g.FillRectangle(Brushes.Magenta, 0, 0, 16, 16)
                   ControlPaint.DrawCheckBox(g, 0, 0, 16, 16, ButtonState.Flat Or ButtonState.Checked)
                   g.Dispose()
                   autObj.ToolBarImage = btmp
                   ' setup the toolbar button tooltip text
                   autObj.ToolBarToolTipText = "CheckBox"
                   ' setup the cursor used when drawing this object
                   autObj.DrawCursor = Cursors.Cross
                   ' setup the context menu for this object
                   ' we will insert a new menu item for "Checked" before the properties menu item
                   Dim cm As ContextMenu = AnnAutomationManager.CreateDefaultObjectContextMenu(autObj.Id)
                   ' add a handler for the Popup event so we can check/uncheck our new menu item
                   AddHandler cm.Popup, AddressOf checkedMenuItem_Popup
                   ' first a new separator 2 items from the end
                   cm.MenuItems.Add(cm.MenuItems.Count - 2, New MenuItem("-"))
                   ' and our menu item
                   Dim checkedMenuItem As New MenuItem("Checked")
                   AddHandler checkedMenuItem.Click, AddressOf checkedMenuItem_Click
                   cm.MenuItems.Add(cm.MenuItems.Count - 2, checkedMenuItem)
                   autObj.ContextMenu = cm
                   ' finally add this object to the automation objects of the manager
                   manager.Objects.Add(autObj)
                End Sub
                Private Sub checkedMenuItem_Popup(ByVal sender As Object, ByVal e As EventArgs)
                   ' check/uncheck the Checked menu item depending on the object state
                   Dim cm As ContextMenu = DirectCast(sender, ContextMenu)
                   Dim automation As AnnAutomation = theManager.Automations(0)
                   Dim obj As MyCheckBoxObject = DirectCast(automation.CurrentEditObject, MyCheckBoxObject)
                   cm.MenuItems(cm.MenuItems.Count - 3).Checked = obj.Checked
                End Sub
                Private Sub checkedMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs)
                   ' check/uncheck the object
                   ' do not forget to add an undo node
                   Dim automation As AnnAutomation = theManager.Automations(0)
                   Dim obj As MyCheckBoxObject = DirectCast(automation.CurrentEditObject, MyCheckBoxObject)
                   automation.BeginUndo()
                   obj.Checked = Not obj.Checked
                   automation.EndUndo()
                   automation.Viewer.Invalidate(obj.InvalidRectangle)
                End Sub
                
    

    [C#]

                private AnnAutomationManager theManager;
                private void Form1_Load(object sender, System.EventArgs e)
                {
                   // load an image into the viewer
                   RasterCodecs codecs = new RasterCodecs();
                   rasterImageViewer1.Image = codecs.Load(@"C:\Users\Public\Documents\LEADTOOLS Images\Sample1.cmp");
                   // create and setup the automation manager
                   theManager = new AnnAutomationManager();
                   // Create the default (all) automation objects.
                   theManager.CreateDefaultObjects();
                   // add our own Triangle and CheckBox as automation objects
                   AddMyTriangleAutomationObject(theManager);
                   AddMyCheckBoxAutomationObject(theManager);
                   // create the toolbar and add it to the form
                   theManager.CreateToolBar();
                   Controls.Add(theManager.ToolBar);
                   theManager.ToolBar.BringToFront();
                   // setup the automation (will create the container as well)
                   AnnAutomation automation = new AnnAutomation(theManager, rasterImageViewer1);
                   // setup this automation as the active one
                   automation.Active = true;
                }
                private void AddMyTriangleAutomationObject(AnnAutomationManager manager)
                {
                   AnnAutomationObject autObj = new AnnAutomationObject();
                   // setup the ID
                   autObj.Id = AnnAutomationManager.UserObjectId;
                   // give it a friendly name
                   autObj.Name = "Triangle";
                   // setup the object template
                   // this the object that will be used when drawing new MyTriangleObject.    so, setup the pen and brush as desired
                   MyTriangleObject obj = new MyTriangleObject();
                   obj.Pen = new AnnPen(Color.Blue, new AnnLength(2, AnnUnit.Pixel));
                   obj.Brush = new AnnSolidBrush(Color.Yellow);
                   autObj.Object = obj;
                   // setup the draw, edit and run designers type
                   autObj.DrawDesignerType = typeof(MyTriangleObjectDrawDesigner);
                   autObj.EditDesignerType = typeof(MyTriangleObjectEditDesigner);
                   // we will use the default run designer for this object
                   autObj.RunDesignerType = typeof(AnnRunDesigner);
                   // we need a toolbar image, so create one
                   Bitmap btmp = new Bitmap(16, 16);
                   using(Graphics g = Graphics.FromImage(btmp))
                   {
                      g.FillRectangle(Brushes.Magenta, 0, 0, 16, 16);
                      g.DrawLine(Pens.Black, 8, 2, 14, 14);
                      g.DrawLine(Pens.Black, 14, 14, 2, 14);
                      g.DrawLine(Pens.Black, 2, 14, 8, 2);
                   }
                   autObj.ToolBarImage = btmp;
                   // setup the toolbar button tooltip text
                   autObj.ToolBarToolTipText = "Triangle";
                   // setup the cursor used when drawing this object
                   autObj.DrawCursor = Cursors.Cross;
                   // setup the context menu for this object
                   // we will use the default context menu
                   autObj.ContextMenu = AnnAutomationManager.CreateDefaultObjectContextMenu(autObj.Id);
                   // finally add this object to the automation objects of the manager
                   manager.Objects.Add(autObj);
                }
                private void AddMyCheckBoxAutomationObject(AnnAutomationManager manager)
                {
                   AnnAutomationObject autObj = new AnnAutomationObject();
                   // setup the ID
                   autObj.Id = AnnAutomationManager.UserObjectId + 1;
                   // give it a friendly name
                   autObj.Name = "CheckBox";
                   // setup the object template
                   // this the object that will be used when drawing new MyCheckBoxObject.    so, setup the brush, font and text
                   MyCheckBoxObject obj = new MyCheckBoxObject();
                   obj.Checked = false;
                   obj.Brush = new AnnSolidBrush(SystemColors.Control);
                   obj.Text = "CheckBox";
                   obj.TextColor = SystemColors.ControlText;
                   obj.Font = new AnnFont("Arial", new AnnLength(8, AnnUnit.Point), FontStyle.Regular);
                   obj.Alignment = StringAlignment.Near;
                   obj.LineAlignment = StringAlignment.Center;
                   autObj.Object = obj;
                   // setup the draw, edit and run designers type
                   // note, MyCheckBoxObject will use the default rectangle draw and edit designers
                   autObj.DrawDesignerType = typeof(AnnRectangleDrawDesigner);
                   autObj.EditDesignerType = typeof(AnnRectangleEditDesigner);
                   // use our run designer
                   autObj.RunDesignerType = typeof(MyCheckBoxObjectRunDesigner);
                   // we need a toolbar image, so create one
                   Bitmap btmp = new Bitmap(16, 16);
                   using(Graphics g = Graphics.FromImage(btmp))
                   {
                      g.FillRectangle(Brushes.Magenta, 0, 0, 16, 16);
                      ControlPaint.DrawCheckBox(g, 0, 0, 16, 16, ButtonState.Flat | ButtonState.Checked);
                   }
                   autObj.ToolBarImage = btmp;
                   // setup the toolbar button tooltip text
                   autObj.ToolBarToolTipText = "CheckBox";
                   // setup the cursor used when drawing this object
                   autObj.DrawCursor = Cursors.Cross;
                   // setup the context menu for this object
                   // we will insert a new menu item for "Checked" before the properties menu item
                   ContextMenu cm = AnnAutomationManager.CreateDefaultObjectContextMenu(autObj.Id);
                   // add a handler for the Popup event so we can check/uncheck our new menu item
                   cm.Popup += new EventHandler(checkedMenuItem_Popup);
                   // first a new seperator 2 items from the end
                   cm.MenuItems.Add(cm.MenuItems.Count - 2, new MenuItem("-"));
                   // and our menu item
                   MenuItem checkedMenuItem = new MenuItem("Checked");
                   checkedMenuItem.Click += new EventHandler(checkedMenuItem_Click);
                   cm.MenuItems.Add(cm.MenuItems.Count - 2, checkedMenuItem);
                   autObj.ContextMenu = cm;
                   // finally add this object to the automation objects of the manager
                   manager.Objects.Add(autObj);
                }
                private void checkedMenuItem_Popup(object sender, EventArgs e)
                {
                   // check/uncheck the Checked menu item depending on the object state
                   ContextMenu cm = sender as ContextMenu;
                   AnnAutomation automation = theManager.Automations[0];
                   MyCheckBoxObject obj = automation.CurrentEditObject as MyCheckBoxObject;
                   cm.MenuItems[cm.MenuItems.Count - 3].Checked = obj.Checked;
                }
                private void checkedMenuItem_Click(object sender, EventArgs e)
                {
                   // check/uncheck the object
                   // do not forget to add an undo node
                   AnnAutomation automation = theManager.Automations[0];
                   MyCheckBoxObject obj = automation.CurrentEditObject as MyCheckBoxObject;
                   automation.BeginUndo();
                   obj.Checked = !obj.Checked;
                   automation.EndUndo();
                   automation.Viewer.Invalidate(obj.InvalidRectangle);
                }
                
    
  10. Add event handlers for Button1, Button2, Button3 and Button3 and add the following code:

    [Visual Basic]

                Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
                   ' Save button clicked
                   Dim codecs As New AnnCodecs
                   codecs.Save("C:\Test.ann", theManager.Automations(0).Container, AnnCodecsFormat.Serialize, 1, AnnCodecsSavePageMode.Overwrite)
                   RasterImageViewer1.Invalidate()
                End Sub 
                
                Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
                   ' Load button clicked
                   Dim codecs As New AnnCodecs
                   theManager.Automations(0).Container.Objects.Clear()
                   codecs.Load("C:\Test.ann", theManager.Automations(0).Container, 1)
                   RasterImageViewer1.Invalidate()
                End Sub
                
                Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
                   ' Clear button clicked
                   theManager.Automations(0).Container.Objects.Clear()
                   RasterImageViewer1.Invalidate()
                   Dim editDesigner As AnnEditDesigner = TryCast(theManager.Automations(0).CurrentDesigner, AnnEditDesigner)
                   If Not editDesigner Is Nothing Then
                     editDesigner.End()
                   End If
                End Sub
                
                Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
                   ' Run/Design button clicked
                   If (theManager.UserMode = AnnUserMode.Design) Then
                      theManager.UserMode = AnnUserMode.Run
                   Else
                      theManager.UserMode = AnnUserMode.Design
                   End If
                End Sub
                
    

    [C#]

                private void button1_Click(object sender, System.EventArgs e)
                {
                   // Save button clicked
                   AnnCodecs codecs = new AnnCodecs();
                   codecs.Save(@"C:\Test.ann", theManager.Automations[0].Container, AnnCodecsFormat.Serialize, 1, AnnCodecsSavePageMode.Overwrite);
                   rasterImageViewer1.Invalidate();
                }
                private void button2_Click(object sender, System.EventArgs e)
                {
                   // Load button clicked
                   AnnCodecs codecs = new AnnCodecs();
                   theManager.Automations[0].Container.Objects.Clear();
                   codecs.Load(@"C:\Test.ann", theManager.Automations[0].Container, 1);
                   rasterImageViewer1.Invalidate();
                }
                private void button3_Click(object sender, System.EventArgs e)
                {
                   // Clear button clicked
                   theManager.Automations[0].Container.Objects.Clear();
                   rasterImageViewer1.Invalidate();
                   AnnEditDesigner editDesigner = theManager.Automations[0].CurrentDesigner as AnnEditDesigner;
                   if(editDesigner != null)
                   {
                     editDesigner.End();
                   }    
                }
                private void button4_Click(object sender, System.EventArgs e)
                {
                   // Run/Design button clicked
                   theManager.UserMode = theManager.UserMode == AnnUserMode.Design ? AnnUserMode.Run : AnnUserMode.Design;
                }
                
    
  11. Build and run the application to test it.
© 1991-2016 LEAD Technologies, Inc. All Rights Reserved.