LEADTOOLS Medical (Leadtools.MedicalViewer assembly) Send comments on this topic. | Back to Introduction - All Topics | Help Version 17.0.3.31
MedicalViewerCustomAnnotationRequestedObject Enumeration
See Also  
Leadtools.MedicalViewer Namespace : MedicalViewerCustomAnnotationRequestedObject Enumeration



Represents the enumeration that will be sent through the MedicalViewerBaseCell.CustomAnnotationDataRequested to the custom annotation object, run designer, or edit designer.

Syntax

Visual Basic (Declaration) 
Public Enum MedicalViewerCustomAnnotationRequestedObject 
   Inherits System.Enum
   Implements IComparableIConvertibleIFormattable 
Visual Basic (Usage)Copy Code
Dim instance As MedicalViewerCustomAnnotationRequestedObject
C# 
public enum MedicalViewerCustomAnnotationRequestedObject : System.Enum, IComparableIConvertibleIFormattable  
C++/CLI 
public enum class MedicalViewerCustomAnnotationRequestedObject : public System.Enum, IComparableIConvertibleIFormattable  

Members

MemberDescription
AnnotationObjectThe request is a new instance of the custom annotation object.
DrawDesignerThe request is a new instance of the custom annotation run designer.
EditDesignerThe request is a new instance of the custom annotation edit designer.

Example

Visual BasicCopy Code
Private Class MedicalViewerCustomAnnotationForm : Inherits Form
      Private _medicalViewer As MedicalViewer
      Private Sub MedicalViewerForm_SizeChanged(ByVal sender As Object, ByVal e As EventArgs)
         _medicalViewer.Size = New Size(Me.ClientRectangle.Right, Me.ClientRectangle.Bottom)
      End Sub

      Public Sub New()
         Dim _codecs As RasterCodecs = New RasterCodecs()
         Dim _image As RasterImage

         AddHandler SizeChanged, AddressOf MedicalViewerForm_SizeChanged

         ' Create the medical viewer and adjust the size and the location.
         _medicalViewer = New MedicalViewer(1, 2)
         _medicalViewer.Location = New Point(0, 0)
         _medicalViewer.Size = New Size(Me.ClientRectangle.Right, Me.ClientRectangle.Bottom)

         ' Load an image and then add it to the control.
         _image = _codecs.Load(Path.Combine(LEAD_VARS.ImagesDir, "xa.dcm"))
         Dim cell As MedicalViewerMultiCell = New MedicalViewerMultiCell(_image, True, 1, 1)
         ' add some action that will be used to change the properties of the images inside the control.
         cell.AddAction(MedicalViewerActionType.WindowLevel)
         cell.AddAction(MedicalViewerActionType.Scale)
         cell.AddAction(MedicalViewerActionType.Offset)

         ' assign the added actions to a mouse button, meaning that when the user click and drag the mouse button, the associated action will be activated.
         cell.SetAction(MedicalViewerActionType.WindowLevel, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active Or MedicalViewerActionFlags.RealTime)
         cell.SetAction(MedicalViewerActionType.Scale, MedicalViewerMouseButtons.Middle, MedicalViewerActionFlags.Active Or MedicalViewerActionFlags.RealTime)
         cell.SetAction(MedicalViewerActionType.Offset, MedicalViewerMouseButtons.Right, MedicalViewerActionFlags.Active Or MedicalViewerActionFlags.RealTime)

         _medicalViewer.Cells.Add(cell)

         ' adjust some properties to the cell and add some tags.
         _medicalViewer.Cells(0).SetTag(2, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.UserData, "EX. ID 230-36-5448")
         _medicalViewer.Cells(0).SetTag(4, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Frame)
         _medicalViewer.Cells(0).SetTag(6, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Scale)
         _medicalViewer.Cells(0).SetTag(2, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.WindowLevelData)
         _medicalViewer.Cells(0).SetTag(1, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.FieldOfView)


         ' Load another image and then add it to the control.
         _image = _codecs.Load(Path.Combine(LEAD_VARS.ImagesDir, "mr.dcm"))
         _medicalViewer.Cells.Add(New MedicalViewerMultiCell(_image, True, 2, 2))

         ' add some action that will be used to change the properties of the images inside the control.
         _medicalViewer.Cells(1).AddAction(MedicalViewerActionType.WindowLevel)
         _medicalViewer.Cells(1).AddAction(MedicalViewerActionType.Scale)
         _medicalViewer.Cells(1).AddAction(MedicalViewerActionType.Offset)

         ' assign the added actions to a mouse button, meaning that when the user click and drag the mouse button, the associated action will be activated.
         _medicalViewer.Cells(1).SetAction(MedicalViewerActionType.WindowLevel, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active Or MedicalViewerActionFlags.RealTime)
         _medicalViewer.Cells(1).SetAction(MedicalViewerActionType.Scale, MedicalViewerMouseButtons.Middle, MedicalViewerActionFlags.Active Or MedicalViewerActionFlags.RealTime)
         _medicalViewer.Cells(1).SetAction(MedicalViewerActionType.Offset, MedicalViewerMouseButtons.Right, MedicalViewerActionFlags.Active Or MedicalViewerActionFlags.RealTime)

         ' adjust some properties to the cell and add some tags.
         _medicalViewer.Cells(1).SetTag(2, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.UserData, "EX. ID 230-36-5448")
         _medicalViewer.Cells(1).SetTag(4, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Frame)
         _medicalViewer.Cells(1).SetTag(6, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Scale)
         _medicalViewer.Cells(1).SetTag(2, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.WindowLevelData)
         _medicalViewer.Cells(1).SetTag(1, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.FieldOfView)


         Controls.Add(_medicalViewer)
         _medicalViewer.Dock = DockStyle.Fill
      End Sub
      Public ReadOnly Property Viewer() As MedicalViewer
         Get
            Return _medicalViewer
         End Get
      End Property
   End Class
   Private Function GetMedicalControlForCustomAnnotationExample() As MedicalViewerCustomAnnotationForm
      Return New MedicalViewerCustomAnnotationForm()
   End Function


   Public Sub MedicalViewerCustomAnnotationExample()
      Dim myForm As MedicalViewerCustomAnnotationForm = GetMedicalControlForCustomAnnotationExample()
      Dim medicalViewer As MedicalViewer = myForm.Viewer
      Dim cell As MedicalViewerMultiCell = CType(medicalViewer.Cells(0), MedicalViewerMultiCell)

      cell.AddAction(CType(101, MedicalViewerActionType))
      cell.SetAction(CType(101, MedicalViewerActionType), MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active Or MedicalViewerActionFlags.RealTime)
      cell.DeclareActionAsAnnotation(CType(101, MedicalViewerActionType), GetType(MyTriangleObject))
      AddHandler cell.CustomAnnotationDataRequested, AddressOf cell_CustomAnnotationDataRequested

      myForm.ShowDialog()
   End Sub

   Private Sub cell_CustomAnnotationDataRequested(ByVal sender As Object, ByVal e As MedicalViewerCustomAnnotationArgs)
      Select Case e.RequestedObject
         Case MedicalViewerCustomAnnotationRequestedObject.AnnotationObject
            If e.AnnotationAction = CType(101, MedicalViewerActionType) Then
               Dim triangle As MyTriangleObject = New MyTriangleObject()
               triangle.Pen = New AnnPen(Color.Blue, New AnnLength(3, AnnUnit.Pixel))
               e.AnnotationObject = triangle
            End If
         Case MedicalViewerCustomAnnotationRequestedObject.DrawDesigner
            If e.AnnotationAction = CType(101, MedicalViewerActionType) Then
               e.DrawDesigner = New MyTriangleObjectDrawDesigner()
            End If
         Case MedicalViewerCustomAnnotationRequestedObject.EditDesigner
            If e.AnnotationAction = CType(101, MedicalViewerActionType) Then
               e.EditDesigner = New MyTriangleObjectEditDesigner()
            End If
      End Select
   End Sub



   '
   ' 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()> _
   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()
         ' no, we do not require a font
         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)
         ' do not forget to call the base class version
         MyBase.New(info, context)
         ' we need to deserialize our private variables here
         _firstPoint = CType(info.GetValue("FirstPointName", GetType(AnnPoint)), AnnPoint)
         _secondPoint = CType(info.GetValue("SecondPointName", GetType(AnnPoint)), AnnPoint)
         _thirdPoint = CType(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 = TryCast(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 GraphicsPath = 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

      Public Overrides Sub ResetRotatePoints()
         ' Place the rotate center control point in the center of the triangle
         Dim CenterX As Single = (FirstPoint.X + SecondPoint.X + ThirdPoint.X) / 3
         Dim CenterY As Single = (FirstPoint.Y + SecondPoint.Y + ThirdPoint.Y) / 3
         RotateCenter = New AnnPoint(CenterX, CenterY)

         ' Place the RotateGripper along a line from the center of the triangle through a vertex
         Dim cx As Single = FirstPoint.X - RotateCenter.X
         Dim cy As Single = FirstPoint.Y - RotateCenter.Y

         Dim dist As Single = CSng(Math.Sqrt(cx * cx + cy * cy))
         Dim fract As Single = 1
         If dist <> 0 Then
            fract = (Math.Abs(dist) + Math.Abs(GripperDistance)) / dist
         End If
         Dim GripperX As Single = CenterX + fract * cx
         Dim GripperY As Single = CenterY + fract * cy
         RotateGripper = New AnnPoint(GripperX, GripperY)
      End Sub
   End Class



   '
   ' 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 DrawObject Is Nothing Then
               ' yes, create a new MyTriangleObject from ObjectTemplate
               Dim obj As MyTriangleObject = TryCast(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 += 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 = TryCast(DrawObject, MyTriangleObject)

               Dim pt As AnnPoint = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit)

               If _clickCount = 1 Then
                  ' second point
                  obj.SecondPoint = pt
                  _clickCount += 1
                  handled = True
               ElseIf _clickCount = 2 Then
                  ' third point
                  obj.ThirdPoint = pt
                  handled = True

                  ' we are done!
                  EndWorking()
               End If
            End If
         Else
            ' we want to cancel the drawing if any other button has been clicked
            If Not DrawObject Is Nothing 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 DrawObject Is Nothing 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 = TryCast(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 DrawObject Is Nothing Then
            handled = True
         End If

         Return handled
      End Function
   End Class


   '
   ' 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 = TryCast(EditObject, MyTriangleObject)
         Return New AnnPoint() {obj.FirstPoint, obj.SecondPoint, obj.ThirdPoint}
      End Function

      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 = TryCast(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


Public NotInheritable Class LEAD_VARS
   Public Const ImagesDir As String = "C:\Users\Public\Documents\LEADTOOLS Images"
End Class
C#Copy Code
class MedicalViewerCustomAnnotationForm : Form
     {
        private MedicalViewer _medicalViewer;
        void MedicalViewerForm_SizeChanged(object sender, EventArgs e)
        {
           _medicalViewer.Size = new Size(this.ClientRectangle.Right, this.ClientRectangle.Bottom);
        }

        public MedicalViewerCustomAnnotationForm()
        {
           RasterCodecs _codecs = new RasterCodecs();
           RasterImage _image;

           this.SizeChanged += new EventHandler(MedicalViewerForm_SizeChanged);

           // Create the medical viewer and adjust the size and the location.
           _medicalViewer = new MedicalViewer(1, 2);
           _medicalViewer.Location = new Point(0, 0);
           _medicalViewer.Size = new Size(this.ClientRectangle.Right, this.ClientRectangle.Bottom);

           // Load an image and then add it to the control.
           _image = _codecs.Load(Path.Combine(LEAD_VARS.ImagesDir,"xa.dcm"));
           MedicalViewerMultiCell cell = new MedicalViewerMultiCell(_image, true, 1, 1);
           // add some action that will be used to change the properties of the images inside the control.
           cell.AddAction(MedicalViewerActionType.WindowLevel);
           cell.AddAction(MedicalViewerActionType.Scale);
           cell.AddAction(MedicalViewerActionType.Offset);

           // assign the added actions to a mouse button, meaning that when the user click and drag the mouse button, the associated action will be activated.
           cell.SetAction(MedicalViewerActionType.WindowLevel, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active | MedicalViewerActionFlags.RealTime);
           cell.SetAction(MedicalViewerActionType.Scale, MedicalViewerMouseButtons.Middle, MedicalViewerActionFlags.Active | MedicalViewerActionFlags.RealTime);
           cell.SetAction(MedicalViewerActionType.Offset, MedicalViewerMouseButtons.Right, MedicalViewerActionFlags.Active | MedicalViewerActionFlags.RealTime);

           _medicalViewer.Cells.Add(cell);

           // adjust some properties to the cell and add some tags.
           _medicalViewer.Cells[0].SetTag(2, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.UserData, "EX. ID 230-36-5448");
           _medicalViewer.Cells[0].SetTag(4, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Frame);
           _medicalViewer.Cells[0].SetTag(6, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Scale);
           _medicalViewer.Cells[0].SetTag(2, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.WindowLevelData);
           _medicalViewer.Cells[0].SetTag(1, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.FieldOfView);


           // Load another image and then add it to the control.
           _image = _codecs.Load(Path.Combine(LEAD_VARS.ImagesDir,"mr.dcm"));
           _medicalViewer.Cells.Add(new MedicalViewerMultiCell(_image, true, 2, 2));

           // add some action that will be used to change the properties of the images inside the control.
           _medicalViewer.Cells[1].AddAction(MedicalViewerActionType.WindowLevel);
           _medicalViewer.Cells[1].AddAction(MedicalViewerActionType.Scale);
           _medicalViewer.Cells[1].AddAction(MedicalViewerActionType.Offset);

           // assign the added actions to a mouse button, meaning that when the user click and drag the mouse button, the associated action will be activated.
           _medicalViewer.Cells[1].SetAction(MedicalViewerActionType.WindowLevel, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active | MedicalViewerActionFlags.RealTime);
           _medicalViewer.Cells[1].SetAction(MedicalViewerActionType.Scale, MedicalViewerMouseButtons.Middle, MedicalViewerActionFlags.Active | MedicalViewerActionFlags.RealTime);
           _medicalViewer.Cells[1].SetAction(MedicalViewerActionType.Offset, MedicalViewerMouseButtons.Right, MedicalViewerActionFlags.Active | MedicalViewerActionFlags.RealTime);

           // adjust some properties to the cell and add some tags.
           _medicalViewer.Cells[1].SetTag(2, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.UserData, "EX. ID 230-36-5448");
           _medicalViewer.Cells[1].SetTag(4, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Frame);
           _medicalViewer.Cells[1].SetTag(6, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Scale);
           _medicalViewer.Cells[1].SetTag(2, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.WindowLevelData);
           _medicalViewer.Cells[1].SetTag(1, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.FieldOfView);


           Controls.Add(_medicalViewer);
           _medicalViewer.Dock = DockStyle.Fill;
        }
        public MedicalViewer Viewer
        {
           get { return _medicalViewer; }
        }
     }
     MedicalViewerCustomAnnotationForm GetMedicalControlForCustomAnnotationExample()
     {
        return new MedicalViewerCustomAnnotationForm();
     }


     public void MedicalViewerCustomAnnotationExample()
     {
        MedicalViewerCustomAnnotationForm myForm = GetMedicalControlForCustomAnnotationExample();
        MedicalViewer medicalViewer = myForm.Viewer;
        MedicalViewerMultiCell cell = (MedicalViewerMultiCell)(medicalViewer.Cells[0]);

        cell.AddAction((MedicalViewerActionType)101);
        cell.SetAction((MedicalViewerActionType)101, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active | MedicalViewerActionFlags.RealTime);
        cell.DeclareActionAsAnnotation((MedicalViewerActionType)101, typeof(MyTriangleObject));
        cell.CustomAnnotationDataRequested += new EventHandler<MedicalViewerCustomAnnotationArgs>(cell_CustomAnnotationDataRequested);

        myForm.ShowDialog();
     }

     void cell_CustomAnnotationDataRequested(object sender, MedicalViewerCustomAnnotationArgs e)
     {
        switch (e.RequestedObject)
        {
           case MedicalViewerCustomAnnotationRequestedObject.AnnotationObject:
              if (e.AnnotationAction == (MedicalViewerActionType)101)
              {
                 MyTriangleObject triangle = new MyTriangleObject();
                 triangle.Pen = new AnnPen(Color.Blue, new AnnLength(3, AnnUnit.Pixel));
                 e.AnnotationObject = triangle;
              }
              break;
           case MedicalViewerCustomAnnotationRequestedObject.DrawDesigner:
              if (e.AnnotationAction == (MedicalViewerActionType)101)
                 e.DrawDesigner = new MyTriangleObjectDrawDesigner();
              break;
           case MedicalViewerCustomAnnotationRequestedObject.EditDesigner:
              if (e.AnnotationAction == (MedicalViewerActionType)101)
                 e.EditDesigner = new MyTriangleObjectEditDesigner();
              break;
        }
     }



     //
     // 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 represents 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;
        }

        public override void ResetRotatePoints()
        {
           // Place the rotate center control point in the center of the triangle
           float CenterX = (FirstPoint.X + SecondPoint.X + ThirdPoint.X) / 3;
           float CenterY = (FirstPoint.Y + SecondPoint.Y + ThirdPoint.Y) / 3;
           RotateCenter = new AnnPoint(CenterX, CenterY);

           // Place the RotateGripper along a line from the center of the triangle through a vertex
           float cx = FirstPoint.X - RotateCenter.X;
           float cy = FirstPoint.Y - RotateCenter.Y;

           float dist = (float)Math.Sqrt(cx * cx + cy * cy);
           float fract = 1;
           if (dist != 0)
              fract = (Math.Abs(dist) + Math.Abs(GripperDistance)) / dist;
           float GripperX = CenterX + fract * cx;
           float GripperY = CenterY + fract * cy;
           RotateGripper = new AnnPoint(GripperX, GripperY);
        }
     }



     //
     // 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++;
                    handled = true;
                 }
                 else if (_clickCount == 2)
                 {
                    // third point
                    obj.ThirdPoint = pt;
                    handled = true;

                    // 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;
        }
     }


     //
     // 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 :
        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
     }


static class LEAD_VARS
{
   public const string ImagesDir = @"C:\Users\Public\Documents\LEADTOOLS Images";
}

Remarks

The annotation as custom must be declared before registering the MedicalViewerBaseCell.CustomAnnotationDataRequested event.

For more information on how to create a custom annotation, refer to the MedicalViewerBaseCell.CustomAnnotationDataRequested event.

Inheritance Hierarchy

System.Object
   System.ValueType
      System.Enum
         Leadtools.MedicalViewer.MedicalViewerCustomAnnotationRequestedObject

Requirements

Target Platforms: Microsoft .NET Framework 2.0, Windows 2000, Windows XP, Windows Server 2003 family, Windows Server 2008 family, Windows Vista, Windows 7

See Also

Leadtools.MedicalViewer requires a Medical Imaging license and unlock key. For more information, refer to: Imaging Pro/Document/Medical Features