Skip to main content
The TTreeConnection class enables visual linking between nodes. Connections are full components with properties, methods, and events, just like nodes.

Overview

Connections display single or multi-line segments between nodes, with optional arrows and customizable styles. They’re automatically managed when nodes move and can adapt to different layout patterns.
// Create a connection
var
  Conn: TTreeConnection;
begin
  Conn := FromNode.AddConnection(ToNode);
  Conn.Border.Color := clBlue;
  Conn.ArrowTo.Size := 8;
end;
Connections are derived from TCustomTreeElement, sharing the base functionality with nodes including text, font, and cursor properties.

Creating Connections

There are several ways to create connections:
// Method 1: Using AddConnection
Connection := Node1.AddConnection(Node2);

// Method 2: Using AddConnectionObject (with data)
Connection := Node1.AddConnectionObject(Node2, MyDataPointer);

// Method 3: Direct creation
Connection := TTreeConnection.Create(Tree);
Connection.FromShape := Node1;
Connection.ToShape := Node2;
Connections are automatically added to the FromShape’s Connections list and the Tree’s connections collection.

Connection Styles

Connections support multiple visual styles:
type
  TTreeConnectionStyle = (
    csAuto,           // Determined by ChildManager
    csLine,           // Straight line
    csSides,          // Multi-segment with sides
    csCurve,          // Curved Bezier line
    csInvertedSides   // Inverted multi-segment
  );

// Apply style
Connection.Style := csCurve;
The ChildManager class determines the connection points and style:
Connection.Style := csAuto;
// Layout controlled by Tree.GlobalFormat.ChildManager
This is the recommended style for hierarchical trees with parent-child relationships.
Direct straight line between nodes:
Connection.Style := csLine;
// Simple point-to-point connection
Multi-segment connection with perpendicular lines:
Connection.Style := csSides;
// Uses Points collection for segments
Smooth Bezier curve:
Connection.Style := csCurve;
// Calculates 100 curve points automatically

Border Styling

Connections use a TTreeConnectionPen for their border:
// Default connection pen settings
with Connection.Border do
begin
  Color := clGray;      // Default gray
  Width := 1;
  Style := psDot;       // Dotted line
  SmallDots := True;    // Smaller dots
end;

// Custom styling
Connection.Border.Color := clBlue;
Connection.Border.Width := 2;
Connection.Border.Style := psSolid;
The default connection pen uses dotted style (psDot) with gray color, making connections visually distinct from nodes.

Arrows

Connections can display arrows at start (From) and end (To) points:

Arrow Styles

type
  TConnectionArrowStyle = (
    casNone,     // No arrow
    casSolid,    // Filled arrow (default for ArrowTo)
    casLines,    // Line arrow
    casSquare,   // Square marker
    casCircle,   // Circular marker
    casDiamond   // Diamond marker
  );

Configuring Arrows

// ArrowFrom (hidden by default)
with Connection.ArrowFrom do
begin
  Style := casSolid;
  Size := 6;
  Brush.Color := clRed;
  Border.Color := clBlack;
end;

// ArrowTo (solid by default)
with Connection.ArrowTo do
begin
  Style := casSolid;     // Default
  Size := 8;
  Brush.Color := clBlue;
  Border.Color := clNavy;
  Border.Width := 1;
end;
ArrowFrom has style casNone by default. You must explicitly set a style to make it visible.

Connection Points

Connections use a TConnectionPoints class to manage their path:
// Access points
PointCount := Connection.Points.Count;

// Add custom points
Connection.Points.Clear;
Connection.Points.Add(100, 50);  // X, Y
Connection.Points.Add(150, 75);
Connection.Points.Add(200, 50);

// Add with styles
Connection.Points.Add(
  cpsFromPercent, 50,   // 50% from FromShape width
  cpsToPercent, 0       // 0% from ToShape height
);

Point Styles

type
  TConnectionPointStyle = (
    cpsAutoFrom,      // Automatic on FromShape
    cpsAutoTo,        // Automatic on ToShape
    cpsFromPercent,   // Percentage of FromShape size
    cpsToPercent,     // Percentage of ToShape size
    cpsFromRel,       // Relative to FromShape origin
    cpsToRel,         // Relative to ToShape origin
    cpsPrevious,      // Relative to previous point
    cpsNext,          // Relative to next point
    cpsFixed          // Fixed pixel position
  );

Point Structure

type
  TConnectionPoint = record
    XStyle: TConnectionPointStyle;
    YStyle: TConnectionPointStyle;
    XValue: TCoordinate;  // Value for X calculation
    YValue: TCoordinate;  // Value for Y calculation
    X: TCoordinate;       // Calculated X position
    Y: TCoordinate;       // Calculated Y position
  end;

Advanced Point Manipulation

// Add point relative to previous
Connection.Points.AddFromPrevious(10, 20);

// Change point style
Connection.Points.ChangeXStyle(0, cpsFixed);
Connection.Points.ChangeYStyle(0, cpsFixed);

// Move point
Connection.Points.Move(0, 5, 10);  // Index, DeltaX, DeltaY

// Insert point
Connection.Points.Insert(1, 125, 60);

// Delete point
Connection.Points.Delete(2);

// Recalculate point position
Connection.Points.CalculatePosition(0);
Points are automatically recalculated when nodes move or the connection is redrawn.

Connection Text

Connections can display text along their path:
// Add text to connection
Connection.SimpleText := 'Connection Label';

// Multi-line text
Connection.Text.Clear;
Connection.Text.Add('Line 1');
Connection.Text.Add('Line 2');

// Text formatting
Connection.Font.Name := 'Arial';
Connection.Font.Size := 10;
Connection.Font.Color := clBlack;
Connection text is drawn at an angle matching the connection line’s direction.

Format Box

Connections have an optional format box for highlighting text:
with Connection.Format do
begin
  Visible := True;
  Brush.Color := clYellow;
  Border.Color := clBlack;
  Transparency := 30;
end;

Managing Connections

Access Node Connections

// Get all connections from a node
for i := 0 to Node.Connections.Count - 1 do
  ProcessConnection(Node.Connections[i]);

// Find connection to specific node
Conn := Node.Connections.ToShape(TargetNode);

if Assigned(Conn) then
  ShowMessage('Connection exists');

// Delete all connections to a node
Node.Connections.DeleteAllTo(TargetNode);

Tree-Level Connection Management

// Access all connections in tree
for i := 0 to Tree.Connections.Count - 1 do
  ProcessConnection(Tree.Connections[i]);

// Selected connection
Tree.Connections.Selected := Connection;

if Assigned(Tree.Connections.Selected) then
  ShowMessage('A connection is selected');

Visibility Control

// Hide individual connection
if not Connection.Visible then
  Exit;

// Hide all connections from a node
Node.Connections.Visible := False;

// Show all connections
Node.Connections.Visible := True;

Hit Testing

// Check if connection is clicked
if Connection.Clicked(MouseX, MouseY) then
  ShowMessage('Connection clicked');

// Find which segment was clicked
Segment := Connection.ClickedSegment(MouseX, MouseY);

if Segment >= 0 then
  ShowMessage('Segment ' + IntToStr(Segment) + ' clicked');

// Find clicked point
PointIndex := Connection.Points.Clicked(MouseX, MouseY);
Hit testing uses TeeLineClickTolerance global variable (default: 3 pixels) for click detection.

Connection Events

// Tree-level connection events
Tree.OnClickConnection := ConnectionClickHandler;
Tree.OnNewConnection := NewConnectionHandler;
Tree.Connections.OnDeleting := ConnectionDeletingHandler;

procedure TForm1.ConnectionClickHandler(Sender: TTreeConnection;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  ShowMessage('Connection clicked: ' +
    Sender.FromShape.SimpleText + ' -> ' +
    Sender.ToShape.SimpleText);
end;

procedure TForm1.ConnectionDeletingHandler(
  Sender: TTreeConnection; var AllowDelete: Boolean);
begin
  // Prevent deletion
  AllowDelete := False;
end;

Deleting Connections

// Delete single connection
Node.Connections.DeleteConnection(Connection);

// Delete from tree level
Tree.Connections.DeleteConnection(Connection);

// Free the connection directly
Connection.Free;
Deleting a node automatically deletes all its connections. You don’t need to manually delete connections when removing nodes.

Cursor Management

// Set custom cursor for connection
Connection.Cursor := crHandPoint;

// Global default cursors
TeeConnectionCursor := crHandPoint;      // Connection hover
TeeConnectionPointCursor := crCross;     // Connection point hover

Drawing and Bounds

// Manually draw connection
if Connection.Draw then
  // Connection was drawn

// Get connection bounds
Bounds := Connection.GetBounds;
Width := Bounds.Right - Bounds.Left;
Height := Bounds.Bottom - Bounds.Top;

// Draw handles (when selected)
Connection.DrawHandles;

Data Association

// Store custom data
Connection.Data := MyDataPointer;
Connection.TagObject := MyObject;
Connection.Tag := 456;

// Retrieve data
MyData := PMyDataType(Connection.Data);
MyObj := Connection.TagObject as TMyClass;

Child Manager Integration

Child managers control automatic connection drawing:
type
  TChildManager = class
    // Override to customize connection drawing
    function DrawConnection(const AConnection: TTreeConnection): Boolean; virtual;
  end;

// Example: Explorer-style connections
function TTreeExplorerAlignChild.DrawConnection(
  const AConnection: TTreeConnection): Boolean;
begin
  Result := True;
  AConnection.Style := csAuto;
  // Child manager sets up Points collection
end;
See Child Managers for details on customizing automatic connection layout.

Common Patterns

Creating Hierarchical Connections

// Connections are auto-created with parent-child relationships
Child := Parent.AddChild('Child');
// Connection automatically created if ChildManager supports it

Custom Connection Path

Connection.Style := csSides;
with Connection.Points do
begin
  Clear;
  Add(cpsAutoFrom, 0, cpsAutoFrom, 0);     // Start at FromShape
  Add(cpsPrevious, 50, cpsPrevious, 0);    // Right 50 pixels
  Add(cpsPrevious, 0, cpsPrevious, 30);    // Down 30 pixels
  Add(cpsAutoTo, 0, cpsAutoTo, 0);         // End at ToShape
end;

Bidirectional Arrows

Connection.ArrowFrom.Style := casSolid;
Connection.ArrowTo.Style := casSolid;

Best Practices

Use csAuto for Hierarchies

Let the ChildManager handle connection layout for parent-child relationships

Style Consistently

Use similar arrow and border styles throughout your tree for visual coherence

Minimize Custom Points

Rely on automatic point calculation when possible for easier maintenance

Handle Events

Use OnClickConnection for interactive connection features

Next Steps

Child Managers

Learn how layouts control connection drawing

Nodes

Understand node properties and methods

Styling Guide

Master visual customization techniques

Build docs developers (and LLMs) love