10

I am looking for a way to be able to use the wpf Path element to draw a path that will represent a route on the map. I have the Route class that contains a collection of vertices and would like to use it for binding. I don't really know how to even start.. Any hints?

2 Answers 2

26

The main thing you'll need for the binding is a converter that turns your points into Geometry which the path will need as Data, here is what my one-way converter from a System.Windows.Point-array to Geometry looks like:

[ValueConversion(typeof(Point[]), typeof(Geometry))]
public class PointsToPathConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Point[] points = (Point[])value;
        if (points.Length > 0)
        {
            Point start = points[0];
            List<LineSegment> segments = new List<LineSegment>();
            for (int i = 1; i < points.Length; i++)
            {
                segments.Add(new LineSegment(points[i], true));
            }
            PathFigure figure = new PathFigure(start, segments, false); //true if closed
            PathGeometry geometry = new PathGeometry();
            geometry.Figures.Add(figure);
            return geometry;
        }
        else
        {
            return null;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }

    #endregion
}

Now all that is really left is to create an instance of it and use it as the converter for the binding. What it might look like in XAML:

<Grid>
    <Grid.Resources>
        <local:PointsToPathConverter x:Key="PointsToPathConverter"/>
    </Grid.Resources>
    <Path Data="{Binding ElementName=Window, Path=Points, Converter={StaticResource ResourceKey=PointsToPathConverter}}"
          Stroke="Black"/>
</Grid>

If you need the binding to update automatically you should work with dependency properties or interfaces like INotifyPropertyChanged/INotifyCollectionChanged

Hope that helps :D

Sign up to request clarification or add additional context in comments.

5 Comments

Awesome. I've written converters before, but somehow I couldn't have figured it out. I was thinking about using DataTemplates or styles or something like this, but this is a great solution. Thank you.
@PortlandRunner: It is just a property of type Point[], debugging individual bindings is not the scope of this answer.
@PortlandRunner: Then i do not understand what it is you are asking for, what is there more to say than it being a point array?
@AutomateThis You should not remove comments. Lol
@WachidSusilo - Oh look, another one was removed ;-)
3

Also you can try it this way:

public static class PathStrings
{
    public const string Add = "F1 M 22,12L 26,12L 26,22L 36,22L 36,26L 26,26L 26,36L 22,36L 22,26L 12,26L 12,22L 22,22L 22,12 Z";
}

Then in the resource create a PathString

<Window.Resources>
    <yourNamespace:PathStrings x:Key="pathStrings"/>
</Window.Resources>

then bind it this way:

<Path Stroke="Black" Fill="Black" 
      Data="{Binding Source={StaticResource pathStrings}, Path=Add}"></Path>

1 Comment

Thanks, I was struggling with this for the last 6 years :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.