We fixed some issues related to the ConnectionManipulationCompleted/Started
events and now they should work as expected. However, as I feel that I might have mislead you regarding the event, let me try to explain how we designed the ConnectionManipulation
Basically when you manipulate a connection you have two
of the process
of a manipulation and end
of the manipulation. When you start manipulating a connection - creating a new connection or detaching a connection, the ConnectionManipulationStarted
event is fired. When the manipulation is in its ending stage - the ConnectionManipulationCompleted
event is fired. And it is important to work with both events in order to cover all parts of a connection manipulation. And it is also very crucial to note that both events are truly preview events
and their purpose
is to allow you to cancel a connection manipulation
This means that the ConnectionManipulationStarted
event is fired before the manipulation on a connection is started - in this case the EventArgs
of the event hold the e.Connection
that is going to be manipulated (or created), and the e.Shape
and the e.Connector
that are part of the manipulation. In case you're starting to drag a new connection out of the connector of a shape, then the ConnectionManipulationStarted
will be fired before the connection is created to allow you to cancel the process and therefore the e.Connection
property will be null, while the e.Shape
properties will hold the shape and the connector where the drag is originating from. And if you're detaching a connection, again you'll have to handle the ConnectionManipulationStarted
event as you're starting to manipulate a connection. When detaching a connection, the e.Connection
property will reflect the connection that is being detached and the e.Shape
property will reflect the shape from which the connection is detached, but the e.Shape IncomingLinks/OutgoingLinks
collections will still hold a reference of the current connection as the ConnectionManipulationStarted
event is a preview event and when it is fired, the connection isn't really detached yet.
The same logic applies for the ConnectionManipulationCompleted
event - it is fired just before a connection manipulation is over - for example when attaching a connection to a shape. Again you'll have a reference of the e.Connection
that is being attached and the e.Shape
where the connection will be attached to, but at this point the connection is still not attached and therefore its SourceShape
properties aren't updated. And you need to consider this fact when working with the event.
Now, let's get back to the scenario you described in the first post of this thread:
1) From a node's connector, drag a new connection.
2) Detach the connection so you end up with a floating one.
3a) Re-attach the tail of the connection to the node's connector. Source is null, target is valid!
3b) Re-attach the head of the connection to the node's connector. Source is null, target is valid!
This is the expected behavior of the ConnectionManipulationCompleted
event - as it is truly a tunneling(preview) event. In 3a) the e.Connection.TargetShape
will be null as the connection isn't yet connected and the operation can be cancelled if you handle the event. But the e.Shape object holds a reference of the shape to which the connection will be connected and the e.Connector object keeps a reference of the object to which the connection is about to be connected. And if you don't plan to handle the event, you can use these properties to update your ViewModels
but only while keeping in mind that the UI isn't yet updated to complete the operation. in 3b) the e.Connection.TargetShape
is set, but the e.Connection.SourceShape
is still null as the event is a preview event And the e.Shape/e.Connector
properties hold a reference to the objects where the head of the connection will be attached to.
Next, you asked - In 3a the target is in fact the source. In 3b the target is indeed the target. How can I distinguish these two scenarios?
- The ManipulationRoutedEventArgs
provides one more property - ManipulationPoint
. It can tell you if you're currently working with the head or tail of a connection. You need to track the e.ManipulationPoint.Type
property to check if you're manipulating the First
point of a connection.
And lastly, please have in mind that it is best to handle both the ConnectionManipulationStarted
events to keep track of the entire manipulation process of a connection.
I hope this information will help you implement your scenario and facilitate your efforts while working with the RadDiagramConnections
the Telerik team