public CanvasContent Deserialize()
        {
            var root = XElement.Load( myReader );

            double offsetX = Double.Parse( root.Attribute( "OffsetX" ).Value, CultureInfo.InvariantCulture );
            double offsetY = Double.Parse( root.Attribute( "OffsetY" ).Value, CultureInfo.InvariantCulture );

            var items = new List<DesignerItem>();

            var itemsXML = root.Elements( "DesignerItems" ).Elements( "DesignerItem" );
            foreach( var itemXML in itemsXML )
            {
                var id = new Guid( itemXML.Element( "ID" ).Value );
                var item = DeserializeDesignerItem( itemXML, id );

                item.SetConnectorDecoratorTemplate();

                items.Add( item );
            }

            var connections = new List<Connection>();

            var connectionsXML = root.Elements( "Connections" ).Elements( "Connection" );
            foreach( var connectionXML in connectionsXML )
            {
                var sourceID = new Guid( connectionXML.Element( "SourceID" ).Value );
                var sinkID = new Guid( connectionXML.Element( "SinkID" ).Value );

                var sourceConnectorName = connectionXML.Element( "SourceConnectorName" ).Value;
                var sinkConnectorName = connectionXML.Element( "SinkConnectorName" ).Value;

                var sourceConnector = GetConnector( items, sourceID, sourceConnectorName );
                var sinkConnector = GetConnector( items, sinkID, sinkConnectorName );

                var connection = new Connection( sourceConnector, sinkConnector );

                connection.SourceArrowSymbol = ( ArrowSymbol )Enum.Parse( typeof( ArrowSymbol ), connectionXML.Element( "SourceArrowSymbol" ).Value );
                connection.SinkArrowSymbol = ( ArrowSymbol )Enum.Parse( typeof( ArrowSymbol ), connectionXML.Element( "SinkArrowSymbol" ).Value );
                connection.IsDotted = connectionXML.Element( "IsDotted" ) != null ? bool.Parse( connectionXML.Element( "IsDotted" ).Value ) : false;

                Canvas.SetZIndex( connection, Int32.Parse( connectionXML.Element( "zIndex" ).Value ) );

                var propertiesContent = ConvertBladeNamespaces(connectionXML.Element("Properties").Value);

                using (var reader = XmlReader.Create(new StringReader(propertiesContent)))
                {
                    var properties = (ItemPropertyCollection)XamlReader.Load(reader);
                    connection.Properties = properties;
                }

                connection.Caption = connectionXML.Element( "Caption" ).Value;

                connections.Add( connection );
            }

            var canvas = new CanvasContent( items, connections );
            canvas.AddOffset( offsetX, offsetY );

            return canvas;
        }
        protected override void OnMouseUp( MouseButtonEventArgs e )
        {
            if ( HitConnector != null )
            {
                var newConnection = new Connection( mySourceConnector, HitConnector );
                newConnection.SinkArrowSymbol = myDesignerCanvas.ArrowStyle;

                Canvas.SetZIndex( newConnection, myDesignerCanvas.Children.Count );
                myDesignerCanvas.Children.Add( newConnection );
            }

            if ( HitDesignerItem != null )
            {
                HitDesignerItem.IsDragConnectionOver = false;
            }

            if ( IsMouseCaptured )
            {
                ReleaseMouseCapture();
            }

            var adornerLayer = AdornerLayer.GetAdornerLayer( myDesignerCanvas );
            if ( adornerLayer != null )
            {
                adornerLayer.Remove( this );
            }
        }
        public ConnectionAdorner( DesignerCanvas designer, Connection connection )
            : base( designer )
        {
            myDesignerCanvas = designer;

            myAdornerCanvas = new Canvas();
            myAdornerCanvas.Focusable = true;
            myAdornerCanvas.IsEnabled = true;

            myVisualChildren = new VisualCollection( this );
            myVisualChildren.Add( myAdornerCanvas );

            myConnection = connection;
            myConnection.PropertyChanged += AnchorPositionChanged;

            InitializeDragThumbs();

            myDrawingPen = new Pen( Brushes.LightSlateGray, 1 );
            myDrawingPen.LineJoin = PenLineJoin.Round;

            Unloaded += OnUnload;
        }
        private XElement Serialize( Connection connection )
        {
            var propertiesXaml = XamlWriter.Save( connection.Properties );

            Contract.Invariant(!string.IsNullOrEmpty(connection.Source.Name), "Source connector name required for serialization");
            Contract.Invariant(!string.IsNullOrEmpty(connection.Sink.Name), "Sink connector name required for serialization");

            return new XElement( "Connection",
                new XElement( "SourceID", myIdTransformation.GetId( connection.Source.ParentDesignerItem.ID ) ),
                new XElement( "SinkID", myIdTransformation.GetId( connection.Sink.ParentDesignerItem.ID ) ),
                new XElement( "SourceConnectorName", connection.Source.Name ),
                new XElement( "SinkConnectorName", connection.Sink.Name ),
                new XElement( "SourceArrowSymbol", connection.SourceArrowSymbol ),
                new XElement( "SinkArrowSymbol", connection.SinkArrowSymbol ),
                new XElement( "IsDotted", connection.IsDotted ),
                new XElement( "zIndex", Canvas.GetZIndex( connection ) ),
                new XElement( "Properties", propertiesXaml ),
                new XElement( "Caption", connection.Caption )
                );
        }