首页 文章

WPF和Adorners

提问于
浏览
3

嗨WPF用户和开发人员 .

我是WPF的新手,我实际上对装饰者有点困惑 . 到目前为止,我了解Adorner是在特定图层(AdornerLayer)中的元素顶部渲染的,该图层是在可视树的更高级别中定义的 .

首先

如何为特定元素创建AdornerLayer,例如形状 .

其次

我想我需要将AdornerLayer添加到Adorned元素的可视子元素中,以便在AdornerLayer中对Adorners进行有效的命中测试 . 怎么做?

先感谢您 .

1 回答

  • 1

    首先,你需要创建一个派生自Adorner的类,如下所示 . 您可以使用拇指或拇指进行渲染 . 这里是我之前实现过的代码,但为了简单起见我稍微改了一些,所以可能会有错误 .

    public class ResizingAdorner : Adorner
    {
        Thumb topLeft;
    
        // To store and manage the adorner's visual children.
        VisualCollection visualChildren;
    
        // Initialize the ResizingAdorner.
        public ResizingAdorner(UIElement adornedElement)
            : base(adornedElement)
        {
            visualChildren = new VisualCollection(this);
            // Call a helper method to initialize the Thumbs
            BuildAdornerCorner(ref topLeft, Cursors.SizeNWSE);
    
            //these are events for the thumbs you may want it or not according to your needs//
            topLeft.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(topLeft_PreviewMouseLeftButtonDown);
            topLeft.DragDelta += new DragDeltaEventHandler(HandleTopLeft);
        }
        //override this method for rendering
        protected override void OnRender(DrawingContext drawingContext)
        {
            Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
            // Some arbitrary drawing implements.
            SolidColorBrush RectBrush = new SolidColorBrush(Colors.Green);
            RectBrush.Opacity = 0.3;
            Pen renderPen = new Pen(RectBrush, 1.5);
            // Draw Rectangle
            drawingContext.DrawRectangle(null, renderPen, adornedElementRect);
        }
    
        // Arrange the Adorners.
        protected override Size ArrangeOverride(Size finalSize)
        {
            Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
            // desiredWidth and desiredHeight are the width and height of the element that's being adorned.  
            // These will be used to place the ResizingAdorner at the corners of the adorned element.  
            double desiredWidth = adornedElementRect.BottomRight.X;
            double desiredHeight = adornedElementRect.BottomRight.Y;
            // adornerWidth & adornerHeight are used for placement as well.
            double adornerWidth = adornedElementRect.TopLeft.X;
            double adornerHeight = adornedElementRect.TopLeft.Y;
            //Arrange PathPoints with the helper Methods
            topLeft.Arrange(new Rect(new Point(adornerWidth, adornerHeight), new Point(desiredWidth, desiredHeight)));
            // Return the final size.
            return finalSize;
        }
        // set some appearance properties, and add the elements to the visual tree//
        void BuildAdornerCorner(ref Thumb cornerThumb, Cursor customizedCursor)
        {
            Path adornered = AdornedElement as Path;
            if (cornerThumb != null) return;
            cornerThumb = new Thumb();
            // Set some arbitrary visual characteristics.
            cornerThumb.Cursor = customizedCursor;
            cornerThumb.Height = cornerThumb.Width = 10;
            cornerThumb.Opacity = 1;
            cornerThumb.Background = new SolidColorBrush(Colors.Black);
    
            visualChildren.Add(cornerThumb);
        }
    
        // UnScale Adorners. this part is optional
        public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
        {
            if (this.visualChildren != null)
            {
                foreach (var thumb in this.visualChildren.OfType<Thumb>())
                {
                    thumb.RenderTransform
                        = new ScaleTransform(1 / ScaleXC, 1 / ScaleYC);
                    thumb.RenderTransformOrigin = new Point(0.5, 0.5);
                }
            }
            return base.GetDesiredTransform(transform);
        }
    }
    

    之后使用如下所示的这个类来装饰元素

    AdornerLayer ADL;  //consider this is as a public field somewhere in your class 
        ...
        ...
        ResizingAdorner A = new XamlEditor.ResizingAdorner(p); // p is an UIElement I my case
        ADL = AdornerLayer.GetAdornerLayer(p);
        ADL.Add(A);
    

相关问题