Search code examples
wpfcanvaspathgeometry

How to create a WPF Path which stretches in places


I'd like to create a WPF control for a window tab, and I want it to have a particular shape. Something like this;

      +------------------------------+
      |                              |
*     |                              |
      |                              |
   +--+                              +--+
6  |                                    |  6
   +------------------------------------+   
     6       stretching section       6

So the little tabs at the bottom left and bottom right are fixed size; 6x6, roughly. But now I want the centre section to stretch out to the width of whatever container I slap it into.

I'm using a Path object at the moment, but I can't figure out how to get a stretching section, or even if Path is the right way to go.

Can anyone suggest the best way to create this kind of half-stretchable shape?


Solution

  • I did the stretching part in my app by creating a "StretchStackPanel" that inherits from StackPanel. The class looks like this:

    public class StretchStackPanel : StackPanel
    {
        public static DependencyProperty StretchDependencyProperty = DependencyProperty.Register("Stretch", typeof(StretchMode), typeof(StretchStackPanel));
    
        protected override Size MeasureOverride(Size availableSize)
        {
            var baseSize = base.MeasureOverride(availableSize);
    
            if (availableSize.Width != double.PositiveInfinity && (Stretch & StretchMode.Horizontal) == StretchMode.Horizontal )
            {
                baseSize.Width = availableSize.Width;    
            }
            if (availableSize.Height != double.PositiveInfinity && (Stretch & StretchMode.Vertical) == StretchMode.Vertical)
            {
                baseSize.Height = availableSize.Height;
            }
    
            return baseSize;
        }
    
        protected override Size ArrangeOverride(Size finalSize)
        {
            var baseSize = base.ArrangeOverride(finalSize);
    
            if ((Stretch & StretchMode.Horizontal) == StretchMode.Horizontal )
            {
                baseSize.Width = finalSize.Width;    
            }
    
            if ((Stretch & StretchMode.Vertical) == StretchMode.Vertical)
            {
                baseSize.Height = finalSize.Height;
            }
            return baseSize;
        }
    
        [Category("Layout")]
        public StretchMode Stretch
        {
            get
            {
                return (StretchMode)GetValue(StretchDependencyProperty);
            }
            set
            {
                SetValue(StretchDependencyProperty, value);
            }
        }
    }
    

    What you want is a Grid with 2 rows. The content of the top row should have it's horizontal alignment set to center. the content of the bottom row should be a StretchStackPanel.