private void AssociatedObject_Drop(object sender, DragEventArgs e)
        {
            //if the data type can be dropped
            if (e.Data.GetDataPresent(typeof(DraggingAdorner)))
            {
                UIElement element = sender as FrameworkElement;

                ICommand dropcommand = GetDropCommand(element);

                if (dropcommand != null)
                {
                    object parameter = GetDropCommandParameter(element);

                    //if (this.AssociatedObject.DataContext is IDragged)
                    //{
                    //    (this.AssociatedObject.DataContext as IDragged).DraggedDataContext = (e.Data.GetDataPresent(DataFormats.Serializable) ? e.Data.GetData(DataFormats.Serializable) : null);
                    //}
                    SetDraggedDataContext(this.AssociatedObject, (e.Data.GetDataPresent(DataFormats.Serializable) ? e.Data.GetData(DataFormats.Serializable) : null));

                    if (dropcommand.CanExecute(parameter))
                    {
                        Point point = e.GetPosition(element);

                        //it is will be to DroopedCanvas is not exist
                        Canvas droppedcanvas = GetDroppedCanvas(element);

                        UIElement dragelement = e.Data.GetDataPresent(typeof(UIElement)) ? e.Data.GetData(typeof(UIElement)) as UIElement : null;

                        Type droppedcontroltype = dragelement != null?GetDroppedControlType(dragelement) : null;

                        if (droppedcontroltype != null && !WPFUtility.IsCorrectType(droppedcontroltype, typeof(ContentControl)))
                        {
                            throw new ArgumentException("DroppedControlType is base on ContentControl.");
                        }

                        if (e.Data.GetDataPresent(typeof(DraggingAdorner)))
                        {
                            var adn = e.Data.GetData(typeof(DraggingAdorner)) as DraggingAdorner;

                            UIElement clnele = null;

                            bool iscopy = false;

                            if (droppedcontroltype != null)
                            {
                                //TODO: Copy Control or create new control
                                if (GetIsDuplication(dragelement))
                                {
                                    clnele = CreateNewContentControl(droppedcontroltype, adn.GetGhostElement() as UIElement);
                                }
                                else
                                {
                                    clnele = Activator.CreateInstance(droppedcontroltype) as UIElement;
                                }
                                iscopy = true;
                            }
                            else
                            {
                                clnele = dragelement;
                            }


                            //add the clone element
                            if (clnele != null)
                            {
                                Point canvaspoint = (Point)(point - adn.CenterPoint);

                                Point oldpoint = new Point(Canvas.GetLeft(dragelement), Canvas.GetTop(dragelement));

                                SetConnectionLinePosition(clnele as ConnectionDiagramBase, (Point)(canvaspoint - oldpoint));


                                Canvas.SetLeft(clnele, canvaspoint.X);
                                Canvas.SetTop(clnele, canvaspoint.Y);

                                var duuid = $"{clnele.GetType().Name}_{Guid.NewGuid().ToString()}";
                                if (clnele is ConnectionDiagramBase)
                                {
                                    (clnele as ConnectionDiagramBase).DiagramUUID = duuid;
                                }
                                else
                                {
                                    FrameworkElementAssist.SetDiagramUUID(clnele, duuid);
                                }

                                if (iscopy)
                                {
                                    if (droppedcanvas != null)
                                    {
                                        droppedcanvas.Children.Add(clnele);
                                    }
                                }
                                else
                                {
                                    //???
                                }

                                if (parameter != null)
                                {
                                    dropcommand.Execute(parameter);
                                }
                                else
                                {
                                    dropcommand.Execute((clnele as ContentControl)?.DataContext);
                                }
                            }
                        }

                        //  }
                    }

                    SetDraggedDataContext(this.AssociatedObject, null);

                    //if (this.AssociatedObject.DataContext is IDragged)
                    //{
                    //    (this.AssociatedObject.DataContext as IDragged).DraggedDataContext = null;
                    //}
                }
            }


            if (this._adorner != null)
            {
                this._adorner.Remove();
            }


            e.Handled = true;
            return;
        }
        private void AssociatedObject_Drop(object sender, DragEventArgs e)
        {
            if (_dataType != null)
            {
                //if the data type can be dropped
                if (e.Data.GetDataPresent(_dataType))
                {
                    FrameworkElement element = sender as FrameworkElement;

                    ICommand dropcommand = GetDropLineCommand(element);

                    if (dropcommand != null)
                    {
                        object parameter = GetDropLineCommandParameter(element);



                        Point point = e.GetPosition(element);

                        var   adn      = e.Data.GetData(_dataType) as DrawLineAdorner;
                        Point adnPoint = adn.Position;

                        Canvas droppedcanvas = GetDroppedLineCanvas(element);

                        var originelement = (e.Data.GetData(typeof(UIElement)) as FrameworkElement);

                        //the object for ConnectionDiagram
                        ConnectionDiagramBase origindiagram   = originelement as ConnectionDiagramBase;
                        ConnectionDiagramBase terminaldiagram = element as ConnectionDiagramBase;

                        SetDraggedDataContext(this.AssociatedObject, e.Data.GetData(DataFormats.Serializable));

                        if (droppedcanvas != null)
                        {
                            double x1, y1, x2, y2 = 0.0;

                            if (ConnectorPositionType.Custom.Equals(origindiagram?.ConnectorPositionType))
                            {
                                //the Ghost line position
                                x1 = adn.GetLineStartEndPosition().Item1;
                                y1 = adn.GetLineStartEndPosition().Item2;
                            }
                            else
                            {
                                x1 = WPFUtility.GetCenterPosition(originelement, droppedcanvas).X;
                                y1 = WPFUtility.GetCenterPosition(originelement, droppedcanvas).Y;
                            }

                            if (ConnectorPositionType.Custom.Equals(terminaldiagram?.ConnectorPositionType))
                            {
                                //the Ghost line position
                                x2 = adn.GetLineStartEndPosition().Item3;
                                y2 = adn.GetLineStartEndPosition().Item4;
                            }
                            else
                            {
                                x2 = WPFUtility.GetCenterPosition(element, droppedcanvas).X;
                                y2 = WPFUtility.GetCenterPosition(element, droppedcanvas).Y;
                            }

                            //the line type of custom
                            Type linetype = GetDropLineControlType(element);

                            if (!WPFUtility.IsCorrectType(linetype, typeof(ConnectionLineBase)))
                            {
                                throw new ArgumentException($"DropLineControlType is base on {nameof(ConnectionLineBase)}.");
                            }

                            dynamic conline;

                            if (!typeof(DrawLineThump).Equals(linetype))
                            {
                                conline = Activator.CreateInstance(linetype);

                                if (conline is ConnectionLineBase)
                                {
                                    //if inherit from ILinePosition
                                    if (conline is ILinePosition)
                                    {
                                        (conline as ILinePosition).X1 = x1;
                                        (conline as ILinePosition).Y1 = y1;
                                        (conline as ILinePosition).X2 = x2;
                                        (conline as ILinePosition).Y2 = y2;
                                    }
                                }
                            }
                            else
                            {
                                conline = new Line()
                                {
                                    X1 = x1,
                                    Y1 = y1,
                                    X2 = x2,
                                    Y2 = y2,
                                };
                            }

                            FrameworkElementAssist.SetOriginDiagram(conline, originelement);
                            FrameworkElementAssist.SetTerminalDiagram(conline, element);


                            //set the parameter
                            //var dropparam = parameter ?? conline.DataContext;
                            string lineuuid = $"{conline.GetType().Name}_{Guid.NewGuid().ToString()}";

                            if (dropcommand.CanExecute(parameter))
                            {
                                Canvas.SetTop(conline, 0);
                                Canvas.SetLeft(conline, 0);

                                //add the relation of the diagram
                                if (origindiagram != null)
                                {
                                    origindiagram.DepartureLines.Add(conline);
                                }
                                if (terminaldiagram != null)
                                {
                                    terminaldiagram.ArrivalLines.Add(conline);
                                }

                                //TODO:FrameworkElement????
                                if (droppedcanvas != null)
                                {
                                    droppedcanvas.Children.Add(conline);
                                }


                                //Set the Dropping Line DataContext
                                SetDroppingDataContext(this.AssociatedObject, conline.DataContext);

                                dropcommand.Execute(parameter);

                                if (conline is ConnectionLineBase)
                                {
                                    (conline as ConnectionLineBase).LineUUID = lineuuid;
                                }
                                else if (conline is Line)
                                {
                                    FrameworkElementAssist.SetLineUUID(conline, lineuuid);
                                }
                            }
                        }
                        else
                        {
                            dropcommand.Execute(parameter);
                        }
                    }
                }
            }

            if (this._adorner != null)
            {
                this._adorner.Remove();
            }


            e.Handled = true;
            return;
        }