private void PositionHandles(Rect elemRect, SizingHandles ignore)
        {
            double halfSize = (SizingHandleSize / 2);

            if (ignore != SizingHandles.TopLeft)
            {
                Canvas.SetLeft(m_handles[(int)SizingHandles.TopLeft], elemRect.Left - halfSize);
                Canvas.SetTop(m_handles[(int)SizingHandles.TopLeft], elemRect.Top - halfSize);
            }

            if (ignore != SizingHandles.TopRight)
            {
                Canvas.SetLeft(m_handles[(int)SizingHandles.TopRight], elemRect.Right - halfSize);
                Canvas.SetTop(m_handles[(int)SizingHandles.TopRight], elemRect.Top - halfSize);
            }

            if (ignore != SizingHandles.BottomLeft)
            {
                Canvas.SetLeft(m_handles[(int)SizingHandles.BottomLeft], elemRect.Left - halfSize);
                Canvas.SetTop(m_handles[(int)SizingHandles.BottomLeft], elemRect.Bottom - halfSize);
            }

            if (ignore != SizingHandles.BottomRight)
            {
                Canvas.SetLeft(m_handles[(int)SizingHandles.BottomRight], elemRect.Right - halfSize);
                Canvas.SetTop(m_handles[(int)SizingHandles.BottomRight], elemRect.Bottom - halfSize);
            }
        }
        protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnPreviewMouseLeftButtonDown(e);

            bool hadSelection = false;

            this.m_isDragging = false;
            this.m_isDraggingHandle = false;

            this.m_origLocation = e.GetPosition(this);

            //  Mark that we had a previously selected element
            if (this.m_selectedElement != null)
                hadSelection = true;

            //  Get the selected element (also the one being dragged)
            this.m_dragElement = this.FindCanvasChild(e.Source as DependencyObject);

            //  If the selection is null, do nothing
            if (this.m_dragElement == null)
            {
                this.m_selectedElement = null;

                //  If we had a previous selection, hide the handles
                if (hadSelection)
                    SetHandleVisibility(false);

                if (OnSelectedElementChanged != null && hadSelection)
                    OnSelectedElementChanged(this, new EventArgs());

                return;
            }

            //  Check if we are dragging a handle
            for (int i = 0; i < m_handles.Length; i++)
            {
                if (this.m_dragElement == m_handles[i])
                {
                    this.m_isDraggingHandle = true;
                    this.m_isDragHandleSelected = (SizingHandles)i;

                    break;
                }
            }

            //  Get the position of the element (NaN's mean the object isn't bound to the side)
            double left = Canvas.GetLeft(this.m_dragElement);
            double right = Canvas.GetRight(this.m_dragElement);
            double top = Canvas.GetTop(this.m_dragElement);
            double bottom = Canvas.GetBottom(this.m_dragElement);

            //  FE of element being dragged
            FrameworkElement fse = (FrameworkElement)this.m_dragElement;

            //  Normalize coordinates of the element (if they're whacko)
            if (Double.IsNaN(left))
            {
                double nl = right - fse.Width;
                Canvas.SetLeft(this.m_dragElement, nl);
                Canvas.SetRight(this.m_dragElement, Double.NaN);
            }
            if (Double.IsNaN(top))
            {
                double nt = bottom - fse.Height;
                Canvas.SetTop(this.m_dragElement, nt);
                Canvas.SetBottom(this.m_dragElement, Double.NaN);
            }

            m_origX = Canvas.GetLeft(this.m_dragElement);
            m_origY = Canvas.GetTop(this.m_dragElement);

            //  If we aren't dragging a handle, cache the rectangle of the selected element
            if (!m_isDraggingHandle)
            {
                if (this.m_dragElement != this.m_selectedElement)
                {
                    this.m_selectedElement = this.m_dragElement;

                    if (OnSelectedElementChanged != null)
                        OnSelectedElementChanged(this, new EventArgs());
                }

                double x = Canvas.GetLeft(this.m_selectedElement);
                double y = Canvas.GetTop(this.m_selectedElement);

                this.m_origSelectedRect = new Rect(x, y, fse.Width, fse.Height);

                //  Position the sizing handles around the object
                PositionHandles(this.m_origSelectedRect, SizingHandles.BottomCentre);

                //  If we didn't have a previous selections, show the handles
                if (!hadSelection)
                    SetHandleVisibility(true);
            }

            this.m_newSelectedRect = this.m_origSelectedRect;

            //  Mark that we will drag
            this.m_isDragging = true;

            //  Mark that we handles the mouse down
            e.Handled = true;
        }