Click here to Skip to main content
13,291,084 members (68,503 online)
Click here to Skip to main content
Add your own
alternative version


551 bookmarked
Posted 24 Feb 2008

WPF Diagram Designer - Part 3

, 29 Feb 2008
Rate this:
Please Sign up or sign in to vote.
Connecting items
WPF FlowChart Designer
  • Part 1 - Features: Drag, resize and rotate items on a canvas
  • Part 2 - Features: Toolbox, drag & drop, rubberband selection


There exist different techniques to connect items in a typical diagram designer. One approach is to provide connection elements in a toolbox which the user can drop on the designer canvas and then drag the endpoints to the source and sink items. Another approach is that the items themselves provide connection points from which the user can drag a connection to other items. This second strategy is the one I will explain in this article.

Use Case: How to Connect Items

I'm sure you know how to connect items in a designer application, but still I will illustrate this in some detail to make it easier to identify which class is involved in which activity.

If you move your mouse over a designer item four visual elements of type Connector will appear at each side of the item. This default layout is defined in the ConnectorDecoratorTemplate and is part of the default DesignerItem template. Now move your mouse over one of the connectors and the cursor changes to a cross. WPF Diagram Designer: Connecting items
If you now click the left mouse button and start dragging, the connector will create an adorner of type ConnectorAdorner. This adorner is responsible for drawing the path between the source connector and the current mouse position. While dragging, the adorner continuously does hit-testing against the DesignerCanvas to check if the mouse is over a potential sink connector. WPF Diagram Designer: Connecting items
If you release the mouse button over a Connector element the ConnectorAdorner creates a new Connection instance and adds it to the designer canvas' children. If the mouse button is released elsewhere no Connection instance is created. WPF Diagram Designer: Connecting items
Like the DesignerItem the Connection implements the ISelectable interface. If a Connection instance is selected you will see two rectangles at each end of the connection path. They belong to an adorner of type ConnectionAdorner which automatically shows up when a Connection instance gets selected.
Note: A ConnectorAdorner belongs to a Connector and a ConnectionAdorner belongs to a Connection.
WPF Diagram Designer: Connecting items
Each of the two rectangles represents a Thumb control and they are part of a ConnectionAdorner instance which allows you to modify existing connections. WPF Diagram Designer: Connecting items
E.g. If you drag the sink thumb of the connection to another connector and release it there, you can re-connect the existing connection.
Note: The ConnectorAdorner and the ConnectionAdorner are similar in what they do, but they differ in how they make use of an Adorner class.
WPF Diagram Designer: Connecting items

How is a Connection Glued to an Item?

The default layout of the connectors is defined in the ConnectorDecoratorTemplate, which is part of the DesignerItem's template:

<ControlTemplate x:Key="ConnectorDecoratorTemplate" TargetType="{x:Type Control}">
  <Grid Margin="-5">
    <s:Connector Orientation="Left" VerticalAlignment="Center"
    <s:Connector Orientation="Top" VerticalAlignment="Top"
    <s:Connector Orientation="Right" VerticalAlignment="Center"
    <s:Connector Orientation="Bottom" VerticalAlignment="Bottom"

A Connector class has a Position property which specifies the relative position of the connector's centre point to the designer canvas. Because the Connector class implements the INotifyPropertyChanged interface it can notify clients that a property value has changed. Now when a designer item changes its position or its size the connector's LayoutUpdated event is automatically fired as part of the WPF layout procedure. And this is when the Position property gets updated and itself fires an event to notify clients.

public class Connector : Control, INotifyPropertyChanged
    private Point position;
    public Point Position
        get { return position; }
            if (position != value)
                position = value;

      public Connector()
          // fired when layout changes
          base.LayoutUpdated += new EventHandler(Connector_LayoutUpdated);

      void Connector_LayoutUpdated(object sender, EventArgs e)
          DesignerCanvas designer = GetDesignerCanvas(this);
          if (designer != null)
              //get center position of this Connector relative to the DesignerCanvas
              this.Position = this.TransformToAncestor(designer).Transform
                   (new Point(this.Width / 2, this.Height / 2));



Now we switch over to the Connection class. The Connection class has a Source and a Sink property, both of type Connector. When the source or sink connector is set we immediately register an event handler that listens to the PropertyChanged event of the connector.

public class Connection : Control, ISelectable, INotifyPropertyChanged
     private Connector source;
     public Connector Source
             return source;
             if (source != value)
                 if (source != null)
                     source.PropertyChanged -=
                         new PropertyChangedEventHandler(OnConnectorPositionChanged);

                 source = value;

                 if (source != null)
                     source.PropertyChanged +=
                         new PropertyChangedEventHandler(OnConnectorPositionChanged);


    void OnConnectorPositionChanged(object sender, PropertyChangedEventArgs e)
        if (e.PropertyName.Equals("Position"))



This snippet shows only the source connector, but the sink connector works analogous. The event handler finally updates the connection path geometry, that's it.

Customize Connectors Layout

The default layout and the number of connectors may not always fit your needs. Take the following example of a triangle shaped Path with a customized DragThumbTemplate (see the previous article on how to customize the DragThumbTemplate).

<Path IsHitTestVisible="False"
      Data="M 0,10 5,0 10,10 Z">
        <Path Fill="Transparent" Stretch="Fill"
                  Data="M 0,10 5,0 10,10 Z"/>

WPF Diagram Designer: Custom connectors

The problem here is that the connectors are only visible when the mouse is over the item. If you try to reach the connector on the left or right side you may have some problems. But the solution comes in the form of an attached property named DesignerItem.ConnectorDecoratorTemplate that lets you define custom templates for the connector decorator. The usage is best explained with an example:

<Path IsHitTestVisible="False"
      Data="M 0,10 5,0 10,10 Z">
  <!--<span class="code-comment"> Custom DragThumb Template --></span>
        <Path Fill="Transparent" Stretch="Fill"
              Data="M 0,10 5,0 10,10 Z"/>
  <!--<span class="code-comment"> Custom ConnectorDecorator Template --></span>
         <Grid Margin="0">
            <s:Connector Orientation="Top" HorizontalAlignment="Center"
                   VerticalAlignment="Top" />
            <s:Connector Orientation="Bottom"  HorizontalAlignment="Center"
                   VerticalAlignment="Bottom" />
            <UniformGrid Columns="2">
               <s:Connector Grid.Column="0" Orientation="Left" />
               <s:Connector Grid.Column="1" Orientation="Right"/>

WPF Diagram Designer: Custom connectors

This solution provides a better result but it still needs some tricky layout, which may not always be feasible. For this I provide a RelativePositionPanel that allows you to position items relative to the bounds of the panel. The following example positions three buttons on a RelativePositionPanel by setting the RelativePosition property, which is an attached property.

   <Button Content="TopLeft" c:RelativePositionPanel.RelativePosition="0,0"/>
   <Button Content="Center" c:RelativePositionPanel.RelativePosition="0.5,0.5"/>
   <Button Content="BottomRight" c:RelativePositionPanel.RelativePosition="1,1"/>

This panel can be quite handy when it comes to arrange connectors:

<Path IsHitTestVisible="False"
      Data="M 9,2 11,7 17,7 12,10 14,15 9,12 4,15 6,10 1,7 7,7 Z">
  <!--<span class="code-comment"> Custom DragThumb Template --></span>
        <Path Fill="Transparent" Stretch="Fill"
              Data="M 9,2 11,7 17,7 12,10 14,15 9,12 4,15 6,10 1,7 7,7 Z"/>
  <!--<span class="code-comment"> Custom ConnectorDecorator Template --></span>
         <c:RelativePositionPanel Margin="-4">
            <s:Connector Orientation="Top"
            <s:Connector Orientation="Left"
            <s:Connector Orientation="Right"
            <s:Connector Orientation="Bottom"
            <s:Connector Orientation="Bottom"

WPF Diagram Designer: Custom connectors


In the next article I will concentrate on commands:

  • Cut, copy, paste
  • Grouping of items
  • Align items
  • Z-ordering (bring to front, send to back,...)


  • 24 February, 2008 -- Original version submitted


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Austria Austria
No Biography provided

You may also be interested in...

Comments and Discussions

QuestionAdd connection without using Adorner Pin
radhwabe15-Jun-16 10:41
memberradhwabe15-Jun-16 10:41 
QuestionConnection Shapes Automatically(wpf c#) Pin
Member 1204014113-May-16 2:08
memberMember 1204014113-May-16 2:08 
QuestionAdd Connector runtime Pin
Member 125088149-May-16 17:44
memberMember 125088149-May-16 17:44 
QuestionChange color of a designer item in the canvas at runtime Pin
albert franz26-Nov-15 10:16
memberalbert franz26-Nov-15 10:16 
Questionhow can i change the connecting line color at runtime ? Pin
Member 115749267-Jul-15 22:47
memberMember 115749267-Jul-15 22:47 
QuestionRemove connection shadow Pin
Saffa Shujah7-Mar-15 2:44
memberSaffa Shujah7-Mar-15 2:44 
AnswerRe: Remove connection shadow Pin
Member 115326478-Apr-15 5:19
memberMember 115326478-Apr-15 5:19 
QuestionOne doubt Pin
Ravishankar chinnur15-Dec-14 0:20
memberRavishankar chinnur15-Dec-14 0:20 
QuestionCreating connections behind in the background Pin
Decarlos12-Dec-14 2:28
memberDecarlos12-Dec-14 2:28 
QuestionHow can i enable connector for 1 Stencil and disable it for 2nd? Pin
Saffa Shujah6-Oct-14 7:09
memberSaffa Shujah6-Oct-14 7:09 
Questionconnector creation Pin
Member 109164965-Jul-14 5:15
memberMember 109164965-Jul-14 5:15 
SuggestionUsing wpf diagram designer as class library Pin
Member 1087019319-Jun-14 1:55
memberMember 1087019319-Jun-14 1:55 
GeneralMy vote of 1 Pin
Member 1087019318-Jun-14 2:19
memberMember 1087019318-Jun-14 2:19 
GeneralMy vote of 1 Pin
Member 1087019313-Jun-14 1:54
memberMember 1087019313-Jun-14 1:54 
QuestionConnectors Pin
Member 1057315617-Feb-14 18:41
memberMember 1057315617-Feb-14 18:41 
AnswerRe: Connectors Pin
Member 1087019319-Jun-14 2:00
memberMember 1087019319-Jun-14 2:00 
QuestionCustom DesignerItem Pin
Citroonek5-Jan-14 7:55
memberCitroonek5-Jan-14 7:55 
AnswerRe: Custom DesignerItem Pin
Member 1092000521-Jul-14 4:52
memberMember 1092000521-Jul-14 4:52 
QuestionConnector in Toolbox Pin
aloktambi14-Aug-13 18:56
memberaloktambi14-Aug-13 18:56 
QuestionOther method of connector creation? Pin
lshah65522-May-13 11:30
memberlshah65522-May-13 11:30 
QuestionTo change Existing symbols in the project. Pin
MayurNavsupe29-Mar-13 2:10
memberMayurNavsupe29-Mar-13 2:10 
QuestionHow can i create double sided arrow ? Pin
gavri200030-Dec-12 7:23
membergavri200030-Dec-12 7:23 
AnswerRe: How can i create double sided arrow ? Pin
jollycode21-Feb-13 4:07
memberjollycode21-Feb-13 4:07 
QuestionRe: How can i create double sided arrow ? Pin
gavri200010-Mar-13 14:19
membergavri200010-Mar-13 14:19 
AnswerRe: How can i create double sided arrow ? Pin
jollycode10-Mar-13 15:09
memberjollycode10-Mar-13 15:09 
Questionhow to get points of shape? Pin
hamidehkarimi2-Oct-12 3:04
memberhamidehkarimi2-Oct-12 3:04 
QuestionHow to draw lines direct from Connector ? Pin
Javidan721-Jun-12 0:46
memberJavidan721-Jun-12 0:46 
Questionwhat if we add rules Pin
rdeschain15-May-12 6:41
memberrdeschain15-May-12 6:41 
QuestionVery cool Pin
CIDev25-Apr-12 12:24
memberCIDev25-Apr-12 12:24 
QuestionSilverlight Pin
Ate9-Feb-12 3:40
memberAte9-Feb-12 3:40 
GeneralMy vote of 5 Pin
ShrishailHalijol11-Jan-12 20:53
memberShrishailHalijol11-Jan-12 20:53 
Questionnew image error Pin
shelby6720-Nov-11 19:50
membershelby6720-Nov-11 19:50 
GeneralMy vote of 5 Pin
emmeric16-Nov-11 13:48
memberemmeric16-Nov-11 13:48 
QuestionHow to add Text to Designer Item in your article [modified] Pin
aloktambi14-Sep-11 3:06
memberaloktambi14-Sep-11 3:06 
GeneralWPF LIST View Pin
saurabhd1314-Jul-11 11:47
membersaurabhd1314-Jul-11 11:47 
GeneralMy vote of 5 Pin
salim4187-Jul-11 2:39
membersalim4187-Jul-11 2:39 
GeneralToolBox and ToolBoxItem do not work as expected while using DataTemplate Pin
Bharat Mane13-Jun-11 2:48
memberBharat Mane13-Jun-11 2:48 
GeneralLooks good! Pin
xzz019529-Oct-10 6:57
memberxzz019529-Oct-10 6:57 
GeneralExtracting information from control Pin
misiek76721-Jul-10 13:24
membermisiek76721-Jul-10 13:24 
GeneralWant to connect with some specific Rules Pin
anilmomin875-Jul-10 1:49
memberanilmomin875-Jul-10 1:49 
GeneralAdding Text Pin
Member 228021615-May-10 1:35
memberMember 228021615-May-10 1:35 
Generalsmall spacing between an item and a Connector Pin
santosh56127-Apr-10 7:00
membersantosh56127-Apr-10 7:00 
GeneralRe: small spacing between an item and a Connector Pin
Mitch Belew27-Mar-12 8:03
memberMitch Belew27-Mar-12 8:03 
QuestionHow to change connector thickness Pin
swati banerjee8-Apr-10 18:43
memberswati banerjee8-Apr-10 18:43 
GeneralYou are the bomb Pin
layinka18-Mar-10 3:32
memberlayinka18-Mar-10 3:32 
QuestionHow to react on a doubleclick of DesignerItem in DesignerCanvas? Pin
Lalaa26-Jan-10 9:18
memberLalaa26-Jan-10 9:18 
GeneralDesignerCanvas in AvalonDock.DocumentPane: connection not visible Pin
pbisiac24-Nov-09 22:50
memberpbisiac24-Nov-09 22:50 
QuestionMultiple Drop Option ? Pin
amitmmehta12-Nov-09 14:34
memberamitmmehta12-Nov-09 14:34 
GeneralView in Web Page Pin
Member 290319911-Nov-09 14:15
memberMember 290319911-Nov-09 14:15 
GeneralSpline Shaped Connectors Pin
Bug Me Not5-Nov-09 21:17
memberBug Me Not5-Nov-09 21:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.171207.1 | Last Updated 29 Feb 2008
Article Copyright 2008 by sukram
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid