locked
"Picture frame" border? RRS feed

  • Question

  •  

    I would like to create an adorner that looks like a picture frame, in that it surrounds its content with a pattern that follows around the border, and is mirrored on opposite sides and top and bottom (I'd show a picture if I could upload an image, hint hint.)

     

    Is there an easy way to accomplish this using vector graphics in WPF?  The problem I have trying to do it using brushes and pens and geometry is, any geometry that I define as a border gets the brush applied "globally" to the entire geometry that the path surrounds.

     

    Thanks,

     

    Allan

    Saturday, February 2, 2008 3:09 AM

Answers

  • You can create add a property to the adorner, if the property value changed, you can change the adorner appearance. The following example shows how to do this.

     

    Code Snippet

    public class MyAdorner : Adorner

    {

        public static readonly DependencyProperty RenderTypeProperty =

            DependencyProperty.Register("RenderType", typeof(AdornerType), typeof(MyAdorner), new FrameworkPropertyMetadata(AdornerType.BlueRed, FrameworkPropertyMetadataOptions.AffectsRender));

     

        public MyAdorner(UIElement adornedElement)

            : base(adornedElement)

        {

        }

     

        protected override void OnRender(DrawingContext drawingContext)

        {

            Rect elementRect = new Rect(this.AdornedElement.DesiredSize);

     

            Rect innerRect = elementRect;

            RectangleGeometry innerGeo = new RectangleGeometry(innerRect);

     

            Rect outerRect = new Rect(elementRect.X - 16, elementRect.Top - 16, elementRect.Width + 32, elementRect.Height + 32);

            RectangleGeometry outerGeo = new RectangleGeometry(outerRect);

     

            Brush outerBrush, innerBrush;

            if (this.RenderType == AdornerType.BlueRed)

            {

                outerBrush = Brushes.Blue;

                innerBrush = Brushes.Red;

            }

            else

            {

                outerBrush = Brushes.Yellow;

                innerBrush = Brushes.Green;

            }

     

            drawingContext.DrawGeometry(null, new Pen(outerBrush, 16), outerGeo);

            drawingContext.DrawGeometry(null, new Pen(innerBrush, 16), innerGeo);

        }

     

        public AdornerType RenderType

        {

            get { return (AdornerType)GetValue(RenderTypeProperty); }

            set { SetValue(RenderTypeProperty, value); }

        }

    }

     

    public enum AdornerType { BlueRed, YellowGreen }

     

     

    Best Regards,

    Wei Zhou

    Monday, February 4, 2008 6:57 AM

All replies

  • These aren't adorners, but they are picture frames.  One is described in a blog entry:

     

    http://www.charlespetzold.com/blog/2007/12/Variable-Width-Lines.html

     

    The other is from Chapter 31 of my book "Applications = Code + Markup":

     

    <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

        <Image Stretch="None">
            <Image.Source>
                <DrawingImage>
                    <DrawingImage.Drawing>
                        <DrawingGroup>

                            <!-- Bitmap image of fixed size. -->
                            <ImageDrawing Rect="5 5 200 240"
                                          ImageSource=
                                "http://www.charlespetzold.com/PetzoldTattoo.jpg" />

                            <!-- Dotted pen for scalloped pattern effect. -->
                            <GeometryDrawing>
                                <GeometryDrawing.Pen>
                                    <Pen Brush="DodgerBlue" Thickness="10"
                                                            DashCap="Round">
                                        <Pen.DashStyle>
                                            <DashStyle Dashes="0 1" />
                                        </Pen.DashStyle>
                                    </Pen>
                                </GeometryDrawing.Pen>

                                <GeometryDrawing.Geometry>
                                    <RectangleGeometry Rect="5 5 200 240" />
                                </GeometryDrawing.Geometry>
                            </GeometryDrawing>

                            <!-- Solid pen to hide half the dotted pen. -->
                            <GeometryDrawing>
                                <GeometryDrawing.Pen>
                                    <Pen Brush="DodgerBlue" Thickness="5" />
                                </GeometryDrawing.Pen>

                                <GeometryDrawing.Geometry>
                                    <RectangleGeometry Rect="2.5 2.5 205 245" />
                                </GeometryDrawing.Geometry>
                            </GeometryDrawing>

                            <!-- Wire to hang the frame on the wall. -->
                            <GeometryDrawing Geometry="M 10 0 L 105 -50 L 200 0" >
                                <GeometryDrawing.Pen>
                                    <Pen Brush="Black" />
                                </GeometryDrawing.Pen>
                            </GeometryDrawing>

                        </DrawingGroup>
                    </DrawingImage.Drawing>
                </DrawingImage>
            </Image.Source>
        </Image>
    </Page>

     

    Saturday, February 2, 2008 4:08 AM
  • Thanks very much for the reply.  Unfortunately neither of those get to what I'm after.  So, here's a picture:

     

    http://cid-04b8feb751da2337.skydrive.live.com/self.aspx/DailyDataExplorer/PictureFrame.gif

     

    The effect I'm wanting is to "paint around", with an arbitrary pattern.

     

    Thanks.

    Saturday, February 2, 2008 6:59 AM
  • You can create add a property to the adorner, if the property value changed, you can change the adorner appearance. The following example shows how to do this.

     

    Code Snippet

    public class MyAdorner : Adorner

    {

        public static readonly DependencyProperty RenderTypeProperty =

            DependencyProperty.Register("RenderType", typeof(AdornerType), typeof(MyAdorner), new FrameworkPropertyMetadata(AdornerType.BlueRed, FrameworkPropertyMetadataOptions.AffectsRender));

     

        public MyAdorner(UIElement adornedElement)

            : base(adornedElement)

        {

        }

     

        protected override void OnRender(DrawingContext drawingContext)

        {

            Rect elementRect = new Rect(this.AdornedElement.DesiredSize);

     

            Rect innerRect = elementRect;

            RectangleGeometry innerGeo = new RectangleGeometry(innerRect);

     

            Rect outerRect = new Rect(elementRect.X - 16, elementRect.Top - 16, elementRect.Width + 32, elementRect.Height + 32);

            RectangleGeometry outerGeo = new RectangleGeometry(outerRect);

     

            Brush outerBrush, innerBrush;

            if (this.RenderType == AdornerType.BlueRed)

            {

                outerBrush = Brushes.Blue;

                innerBrush = Brushes.Red;

            }

            else

            {

                outerBrush = Brushes.Yellow;

                innerBrush = Brushes.Green;

            }

     

            drawingContext.DrawGeometry(null, new Pen(outerBrush, 16), outerGeo);

            drawingContext.DrawGeometry(null, new Pen(innerBrush, 16), innerGeo);

        }

     

        public AdornerType RenderType

        {

            get { return (AdornerType)GetValue(RenderTypeProperty); }

            set { SetValue(RenderTypeProperty, value); }

        }

    }

     

    public enum AdornerType { BlueRed, YellowGreen }

     

     

    Best Regards,

    Wei Zhou

    Monday, February 4, 2008 6:57 AM