A recursive line is a line whose Start and End is joined to the same shape. To display this kind of line correctly one should add a port to each side of the shape required so that the line is properly visible.
The Model class has an existing method AddRecursive method which will add a connector to the ports, creating a recursive line made out of straight line segments. To add a curved loop instead of a connector, we need to create a subclass of the Curve class which is defined as follows
Option Explicit On
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Runtime.Serialization
Imports Crainiate.ERM4
Public Class RecursiveLoop
Inherits Curve
Public Sub New(ByVal startPort As Port, ByVal endPort As Port)
MyBase.new(startPort, endPort)
CurveType = CurveType.Bezier
AllowMove = False
MyBase.Start.AllowMove = False
MyBase.End.AllowMove = False
End Sub
Public Sub New(ByVal prototype As RecursiveLoop)
MyBase.New(prototype)
End Sub
Public Overrides Sub DrawPath()
If Container Is Nothing Then Return
If MyBase.Start Is Nothing Then Return
If MyBase.End Is Nothing Then Return
Dim startLocation As PointF = GetOriginLocation(MyBase.Start, MyBase.End)
Dim endLocation As PointF = GetOriginLocation(MyBase.End, MyBase.Start)
Dim controlPoint1 As New PointF(startLocation.X + 60, startLocation.Y - 40)
Dim controlPoint2 As New PointF(endLocation.X + 5, endLocation.Y - 80)
SetControlPoints(New PointF() {controlPoint1, controlPoint2})
MyBase.DrawPath()
End Sub
Public Overrides Function Handle(ByVal location As System.Drawing.PointF) As Handle
Return New Handle(HandleType.Arrow)
End Function
Protected Overrides Sub RenderAction(ByVal graphics As System.Drawing.Graphics, ByVal render As IRender, ByVal renderDesign As IRenderDesign)
DrawPath()
MyBase.RenderAction(graphics, render, renderDesign)
End Sub
Public Overrides Function Clone() As Object
Return New RecursiveLoop(Me)
End Function
End Class
To use the RecursiveLoop class, add the following code to a project using the ERM4 Diagram control, version 4.2435 or later
Private Sub frmDiagram_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim shape As New shape
Dim top As New Port(PortOrientation.Top)
Dim right As New Port(PortOrientation.Right)
top.Visible = False
right.Visible = False
top.Style = PortStyle.Simple
right.Style = PortStyle.Simple
shape.Ports.Add("top", top)
shape.Ports.Add("right", right)
shape.Location = New PointF(100, 100)
model1.Shapes.Add("Shape1", shape)
Dim curve As New RecursiveLoop(right, top)
curve.End.Marker = New Arrow
model1.Lines.Add("Line1", curve)
End Sub