Search code examples
c#wpfwinui-3winui

Cant override DefiningGeometry of Shape in WinUI 3


i'm trying to create a Custom Shape (Triangle) but I can't find the right way to get a Custom Shape working.

In WPF I'm used to overriding DefiningGeometry, but using WinUI 3 there is nothing like it.

Using WPF:

public class Triangle : Shape
{
    private double size;

    public static readonly DependencyProperty SizeProperty = DependencyProperty.Register("Size", typeof(Double), typeof(Triangle));

    public Triangle()
    {
    }

    public double Size
    {
        get { return (double)this.GetValue(SizeProperty); }
        set { this.SetValue(SizeProperty, value); }
    }

    protected override Geometry DefiningGeometry
    {
        get
        {
            Point p1 = new Point(0.0d, 0.0d);
            Point p2 = new Point(this.Size, 0.0d);
            Point p3 = new Point(this.Size / 2, -this.Size);

            List<PathSegment> segments = new List<PathSegment>(3);
            segments.Add(new LineSegment(p1, true));
            segments.Add(new LineSegment(p2, true));
            segments.Add(new LineSegment(p3, true));

            List<PathFigure> figures = new List<PathFigure>(1);
            PathFigure pf = new PathFigure(p1, segments, true);
            figures.Add(pf);

            Geometry g = new PathGeometry(figures, FillRule.EvenOdd, null);

            return g;
        }
    }
}

How can i do this using WinUI 3?


Solution

  • As is suggested in the comments, you need to use Path.

    using Microsoft.UI.Xaml.Media;
    using Microsoft.UI.Xaml.Shapes;
    using Microsoft.UI.Xaml;
    using Windows.Foundation;
    
    namespace ShapeTest;
    
    public class Triangle : Path
    {
        public static readonly DependencyProperty SizeProperty = DependencyProperty.Register(
            nameof(Size),
            typeof(double),
            typeof(Triangle),
            new PropertyMetadata(0.0));
    
        public Triangle()
        {
            this.Loaded += Triangle_Loaded;
        }
    
        public double Size
        {
            get => (double)GetValue(SizeProperty);
            set => SetValue(SizeProperty, value);
        }
        private void Triangle_Loaded(object sender, RoutedEventArgs e)
        {
            Data = new GeometryGroup()
            {
                Children = new GeometryCollection()
                {
                    new LineGeometry()
                    {
                        StartPoint = new Point(0, 0),
                        EndPoint = new Point(0, Size),
                    },
                    new LineGeometry()
                    {
                        StartPoint = new Point(0, Size),
                        EndPoint = new Point(Size / 2, -Size),
                    },
                    new LineGeometry()
                    {
                        StartPoint = new Point(Size / 2, -Size),
                        EndPoint = new Point(0, 0),
                    }
                }
            };
        }
    }
    
    <Grid>
        <local:Triangle
            Size="300"
            Stroke="HotPink"
            StrokeThickness="1" />
    </Grid>