Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.6k views
in Technique[技术] by (71.8m points)

wpf - How to make the contents of a round-cornered border be also round-cornered?

I have a border element with rounded corners containing a 3x3 grid. The corners of the grid are sticking out of the border. How can I fix that? I tried using ClipToBounds but didn't get anywhere. Thanks for your help

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Here are the highlights of this thread mentioned by Jobi

  • None of the decorators (i.e. Border) or layout panels (i.e. Stackpanel) come with this behavior out-of-the-box.
  • ClipToBounds is for layout. ClipToBounds does not prevent an element from drawing outside its bounds; it just prevents children's layouts from 'spilling'. Additionally ClipToBounds=True is not needed for most elements because their implementations dont allow their content's layout to spill anyway. The most notable exception is Canvas.
  • Finally Border considers the rounded corners to be drawings inside the bounds of its layout.

Here is an implementation of a class that inherits from Border and implements the proper functionality:

     /// <Remarks>
    ///     As a side effect ClippingBorder will surpress any databinding or animation of 
    ///         its childs UIElement.Clip property until the child is removed from ClippingBorder
    /// </Remarks>
    public class ClippingBorder : Border {
        protected override void OnRender(DrawingContext dc) {
            OnApplyChildClip();            
            base.OnRender(dc);
        }

        public override UIElement Child 
        {
            get
            {
                return base.Child;
            }
            set
            {
                if (this.Child != value)
                {
                    if(this.Child != null)
                    {
                        // Restore original clipping
                        this.Child.SetValue(UIElement.ClipProperty, _oldClip);
                    }

                    if(value != null)
                    {
                        _oldClip = value.ReadLocalValue(UIElement.ClipProperty);
                    }
                    else 
                    {
                        // If we dont set it to null we could leak a Geometry object
                        _oldClip = null;
                    }

                    base.Child = value;
                }
            }
        }

        protected virtual void OnApplyChildClip()
        {
            UIElement child = this.Child;
            if(child != null)
            {
                _clipRect.RadiusX = _clipRect.RadiusY = Math.Max(0.0, this.CornerRadius.TopLeft - (this.BorderThickness.Left * 0.5));
                _clipRect.Rect = new Rect(Child.RenderSize);
                child.Clip = _clipRect;
            }
        }

        private RectangleGeometry _clipRect = new RectangleGeometry();
        private object _oldClip;
    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...