How can I draw a border with squared corners in wpf?

后端 未结 2 1888
终归单人心
终归单人心 2020-12-10 19:54

You know, like Battlestar paper! I have given this a few goes but now I\'m stumped. I haven\'t yet gone down the geometery route, so I\'ll explain this as best as I can.

相关标签:
2条回答
  • 2020-12-10 20:13

    The WPF border is inheriting from class Decorator. It is pretty easy to write your own Decorator. Below one draws a border around a child with "tucked in" corners.

    class FunkyBorder : Decorator
    {
        public Brush BorderBrush
        {
            get { return (Brush)GetValue(BorderBrushProperty); }
            set { SetValue(BorderBrushProperty, value); }
        }
    
        public static readonly DependencyProperty BorderBrushProperty =
            DependencyProperty.Register("BorderBrush", 
                                        typeof(Brush), 
                                        typeof(FunkyBorder), 
                                        new UIPropertyMetadata(Brushes.Transparent));
    
        protected override void OnRender(DrawingContext drawingContext)
        {
            // TODO, make pen thickness and corner width (currently 10) into dependency properties.
            // Also, handle case when border don't fit into given space without overlapping.
    
            if (_pen.Brush != BorderBrush)
            {
                _pen.Brush = BorderBrush;
            }
    
            drawingContext.DrawLine(_pen, new Point(0, 10), new Point(10, 0));
            drawingContext.DrawLine(_pen, new Point(10, 0), new Point(ActualWidth - 10, 0));
            drawingContext.DrawLine(_pen, new Point(ActualWidth - 10, 0), new Point(ActualWidth, 10));
            drawingContext.DrawLine(_pen, new Point(0, 10), new Point(0, ActualHeight - 10));
            drawingContext.DrawLine(_pen, new Point(ActualWidth, 10), new Point(ActualWidth, ActualHeight - 10));
            drawingContext.DrawLine(_pen, new Point(0, ActualHeight - 10), new Point(10, ActualHeight));
            drawingContext.DrawLine(_pen, new Point(10, ActualHeight), new Point(ActualWidth - 10, ActualHeight));
            drawingContext.DrawLine(_pen, new Point(ActualWidth - 10, ActualHeight), new Point(ActualWidth, ActualHeight - 10));
        }
    
        private Pen _pen = new Pen(Brushes.Transparent, 2);
    }
    

    Use like this:

       <BorderTest:FunkyBorder BorderBrush="Red">
            <TextBlock Text="Hello" />
        </BorderTest:FunkyBorder>
    
    0 讨论(0)
  • 2020-12-10 20:13

    To avoid the nasty breaks at the end, you could use a Polygon or PolyLine:

        <Polygon
            Stroke="Red"
            StrokeThickness="2"
            Points="
                0,1 1,0
                1,0 20,0
                20,0 21,1
                21,1 21,20
                21,20 20,21
                20,21 1,21
                1,21 0,20
                0,1 1,0
            "
            Stretch="Fill"
            />
    

    The width I picked is arbitrary...

    0 讨论(0)
提交回复
热议问题