none
WPF如何做出如下图这种效果,四周可以拉伸,上面中间可以旋转? RRS feed

答案

全部回复

  • 你好

    实现过程应该是这样的:

    矩形在点击后,出现周围的编辑框和中间的旋转按钮

    编辑框上的 8 个点,鼠标选中拖拽时,根据鼠标的位置差,决定矩形的 Width Height 和 Margin 属性,注意 4 个角和 4 个中心点的拖拽,行为稍有不同;

    中间的旋转按钮,可以根据鼠标前后位置的角度差,来设定矩形的 rotatetransform,实现旋转。

    以上都是思路,具体的代码实现需要你自己去查看文档和实现,这样才能真的学到,加油!


    希望我的答案能帮助更多的人。
    博客地址: http://www.cnblogs.com/shaomeng


    2017年11月17日 2:36
  • Hi,

    尝试使用WPF的Adorner来处理。

    以下代码没有实现旋转功能,但是实现了拖拽功能。旋转功能你可以尝试使用WPFRotate变换来处理。

     public class ResizeAdorner : Adorner
        {
            const double THUMB_SIZE = 10;
            const double MINIMAL_SIZE = 20;
            const double MOVE_OFFSET = 20;
    
            //9 thumbs
            /*                        moveAndRotateThumb
             *                              *
             *                              *
             * topLeftThumb*************topMiddleThumb**************topRightThumb        
             *      *                                                    *
             *      *                                                    *
             *      *                                                    *
             * middleLeftThumb                                     middleRightThumb
             *      *                                                    *
             *      *                                                    *
             *      *                                                    * 
             * bottomLeftThumb*********bottomMiddleThumb**************bottomRightThumb
             * 
             * */
            Thumb moveAndRotateThumb, topLeftThumb, middleLeftThumb, bottomLeftThumb, topMiddleThumb,topRightThumb, middleRightThumb, bottomRightThumb ,bottomMiddleThumb;
    
            Rectangle thumbRectangle;
         
    
            VisualCollection visualCollection;
    
            public ResizeAdorner(UIElement adorned): base(adorned)
            {
                visualCollection = new VisualCollection(this);
    
                visualCollection.Add(thumbRectangle = GeteResizeRectangle());
    
                visualCollection.Add(topLeftThumb = GetResizeThumb(Cursors.SizeNWSE, HorizontalAlignment.Left, VerticalAlignment.Top));
                visualCollection.Add(middleLeftThumb = GetResizeThumb(Cursors.SizeWE, HorizontalAlignment.Left, VerticalAlignment.Center));
                visualCollection.Add(bottomLeftThumb = GetResizeThumb(Cursors.SizeNESW, HorizontalAlignment.Left, VerticalAlignment.Bottom));
              
                visualCollection.Add(topRightThumb = GetResizeThumb(Cursors.SizeNESW, HorizontalAlignment.Right, VerticalAlignment.Top));
                visualCollection.Add(middleRightThumb = GetResizeThumb(Cursors.SizeWE, HorizontalAlignment.Right, VerticalAlignment.Center));
                visualCollection.Add(bottomRightThumb = GetResizeThumb(Cursors.SizeNWSE, HorizontalAlignment.Right, VerticalAlignment.Bottom));
    
                visualCollection.Add(topMiddleThumb = GetResizeThumb(Cursors.SizeNS, HorizontalAlignment.Center, VerticalAlignment.Top));
                visualCollection.Add(bottomMiddleThumb = GetResizeThumb(Cursors.SizeNS, HorizontalAlignment.Center, VerticalAlignment.Bottom));
    
                visualCollection.Add(moveAndRotateThumb = GetMoveAndRotateThumb());
    
          
            }  
            private Rectangle GeteResizeRectangle()
            {
                var rectangle = new Rectangle()
                {
                    Width = AdornedElement.RenderSize.Width,
                    Height = AdornedElement.RenderSize.Height,
                    Fill = Brushes.Transparent,
                    Stroke = Brushes.Green,
                    StrokeThickness = (double)1
                };
                return rectangle;
            }
    
            private Thumb GetResizeThumb(Cursor cur, HorizontalAlignment horizontal, VerticalAlignment vertical)
            {
                var thumb = new Thumb()
                {
                    //Background = Brushes.Red,
                    Width = THUMB_SIZE,
                    Height = THUMB_SIZE,
                    HorizontalAlignment = horizontal,
                    VerticalAlignment = vertical,
                    Cursor = cur,
                    Template = new ControlTemplate(typeof(Thumb))
                    {                     
                       VisualTree = GetThumbTemple(new SolidColorBrush(Colors.White))
                    }
                };
                thumb.DragDelta += (s, e) =>
                {
                    var element = AdornedElement as FrameworkElement;
    
                    if (element == null)
                        return;
    
                    this.ElementResize(element);
    
                    switch (thumb.VerticalAlignment)
                    {
                        case VerticalAlignment.Bottom:
                            if (element.Height + e.VerticalChange > MINIMAL_SIZE)
                            {
                                element.Height += e.VerticalChange;
                                thumbRectangle.Height += e.VerticalChange;
                            }
                            break;
    
                        //case VerticalAlignment.Center:
                        //    if ()
                        //    {
    
                        //    }
                        //    break;
                        case VerticalAlignment.                        if (element.Height - e.VerticalChange > MINIMAL_SIZE)
                            {
                                element.Height -= e.VerticalChange;
                                thumbRectangle.Height -= e.VerticalChange;
    
                                Canvas.SetTop(element, Canvas.GetTop(element) + e.VerticalChange);
                            }
                            break;
                    }
                    switch (thumb.HorizontalAlignment)
                    {
                        case HorizontalAlignment.                        if (element.Width - e.HorizontalChange > MINIMAL_SIZE)
                            {
                                element.Width -= e.HorizontalChange;
                                thumbRectangle.Width -= e.HorizontalChange;
                                Canvas.SetLeft(element, Canvas.GetLeft(element) + e.HorizontalChange);
                            }
                            break;
                        //case HorizontalAlignment.Center:
                        //    if (element.Width + e.HorizontalChange > MINIMAL_SIZE)
                        //    {
                        //        element.Width += e.HorizontalChange;
                        //    }
                        //    break;
                        case HorizontalAlignment.Right:
                            if (element.Width + e.HorizontalChange > MINIMAL_SIZE)
                            {
                                element.Width += e.HorizontalChange;
                                thumbRectangle.Width += e.HorizontalChange;
                            }
                            break;
                    }
    
                    e.Handled = true;
                };
                return thumb;
            }
    
            private void ElementResize(FrameworkElement frameworkElement)
            {
                if (Double.IsNaN(frameworkElement.Width))
                    frameworkElement.Width = frameworkElement.RenderSize.Width;
                if (Double.IsNaN(frameworkElement.Height))
                    frameworkElement.Height = frameworkElement.RenderSize.Height;
            }
    
            // get Thumb Temple
            private FrameworkElementFactory GetThumbTemple(Brush back)
            {
                back.Opacity = 1;
                var fef = new FrameworkElementFactory(typeof(Ellipse));
                fef.SetValue(Ellipse.FillProperty, back);
                fef.SetValue(Ellipse.StrokeProperty, Brushes.Green);
                fef.SetValue(Ellipse.StrokeThicknessProperty, (double)1);
                return fef;
            }
    
            private Thumb GetMoveAndRotateThumb()
            {
                var thumb = new Thumb()
                {
                    Width = THUMB_SIZE,
                    Height = THUMB_SIZE,
                    Cursor = wpfDecorator.CursorHelper.CreateCursor(@"..\..\wpfAdorner\旋转.png", 8,8),
                    Template = new ControlTemplate(typeof(Thumb))
                    {
                        VisualTree = GetThumbTemple(GetMoveEllipseBack())
                    }
                };
                thumb.DragDelta += (s, e) =>
                {
                    var element = AdornedElement as FrameworkElement;
                    if (element == null)
                        return;
    
                    Canvas.SetLeft(element, Canvas.GetLeft(element) + e.HorizontalChange);
                    Canvas.SetTop(element, Canvas.GetTop(element) + e.VerticalChange);
                };
                return thumb;
            }
    
            private Brush GetMoveEllipseBack()
            {
                string lan = "M841.142857 570.514286c0 168.228571-153.6 336.457143-329.142857 336.457143s-329.142857-153.6-329.142857-336.457143c0-182.857143 153.6-336.457143 329.142857-336.457143v117.028571l277.942857-168.228571L512 0v117.028571c-241.371429 0-438.857143 197.485714-438.857143 453.485715S270.628571 1024 512 1024s438.857143-168.228571 438.857143-453.485714h-109.714286z m0 0";
                var converter = TypeDescriptor.GetConverter(typeof(Geometry));
                var geometry = (Geometry)converter.ConvertFrom(lan);
                TileBrush bsh = new DrawingBrush(new GeometryDrawing(Brushes.Transparent, new Pen(Brushes.Black, 2), geometry));
                bsh.Stretch = Stretch.Fill;
                return bsh;
            }
    
            protected override Size ArrangeOverride(Size finalSize)
            {
                double offset = (THUMB_SIZE / 2);
                Size sz = new Size(THUMB_SIZE, THUMB_SIZE);
    
                topLeftThumb.Arrange(new Rect(new Point(-offset, -offset), sz));
                topMiddleThumb.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width / 2 - THUMB_SIZE / 2, -offset), sz));
                topRightThumb.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width - offset, -offset), sz));
    
                bottomLeftThumb.Arrange(new Rect(new Point(-offset, AdornedElement.RenderSize.Height - offset), sz));
                bottomMiddleThumb.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width / 2 - THUMB_SIZE / 2, AdornedElement.RenderSize.Height - offset), sz)); 
                bottomRightThumb.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width - offset, AdornedElement.RenderSize.Height - offset), sz));
    
                middleLeftThumb.Arrange(new Rect(new Point(-offset, AdornedElement.RenderSize.Height/2- THUMB_SIZE / 2), sz));
                middleRightThumb.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width - offset, AdornedElement.RenderSize.Height/2 - THUMB_SIZE / 2), sz));
    
                moveAndRotateThumb.Arrange(new Rect(new Point(AdornedElement.RenderSize.Width / 2 - THUMB_SIZE / 2, -MOVE_OFFSET), sz));          
    
                thumbRectangle.Arrange(new Rect(new Point(-offset, -offset), new Size (Width = AdornedElement.RenderSize.Width + THUMB_SIZE, Height = AdornedElement.RenderSize.Height + THUMB_SIZE)));            
             
                return finalSize;
            }
    
            protected override Visual GetVisualChild(int index)
            {
                return visualCollection[index];
            }
    
            protected override int VisualChildrenCount
            {
                get
                {
                    return visualCollection.Count;
                }
            }
    
        }

    http://blog.csdn.net/hjnth/article/details/56483935

    https://www.mgenware.com/blog/?p=16

    Sincerely,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    2017年11月18日 18:30
    版主
  • 非常感谢您的回复,我亲自试下。
    • 已标记为答案 Marry_qing 2017年11月21日 10:50
    2017年11月21日 10:50