Wpf C# Path: How to Get from a String with Path Data to Geometry in Code (Not in Xaml)

WPF C# Path: How to get from a string with Path Data to Geometry in Code (not in XAML)

var path = new Path();
path.Data = Geometry.Parse("M 100,200 C 100,25 400,350 400,175 H 280");

Path.Data is of type Geometry. Using Reflector JustDecompile (eff Red Gate), I looked at the definition of Geometry for its TypeConverterAttribute (which the xaml serializer uses to convert values of type string to Geometry). This pointed me to the GeometryConverter. Checking out the implementation, I saw that it uses Geometry.Parse to convert the string value of the path to a Geometry instance.

WPF; Convert between Path Markup Syntax and Geometry in code behind

What about

Geometry myGeometry = //some geometry
string pathMarkup = myGeometry.ToString();

How to replace Data of XAML Path by C#

You will need to Bind it.

C#:

public PathGeometry Geometry
{
get
{
return pathGeometry ;
}
}

XAML:

<Path Data="{Binding Path=chartmaker.Geometry}"/>

Setting Path.Data in code-behind

I had this probelm too a while ago in winrt. It seems that you cannot asign a "path" value directly in code behind.

However there is a solution here

I used this class in winrt without any problem. All I had to do is change the signatures of the Convert and ConvertBack methods to implement the IValueConverter interface as it is in winrt and not in silverlight.
Here they are

public object Convert(object value, Type targetType, object parameter, string language)
{
string path = value as string;
if (null != path)
return Convert(path);
else
return null;
}

public object ConvertBack(object value, Type targetType, object parameter, string language)
{
PathGeometry geometry = value as PathGeometry;

if (null != geometry)
return ConvertBack(geometry);
else
return default(string);
}

Usage: (More or less)

var stringToPathGeometryConverter = new StringToPathGeometryConverter();
string pathData = "m 150,0 A 150,0 0 0 0 150,0 A 150,150 0 0 0 150,0" ;
progressPath.Data = stringToPathGeometryConverter.Convert(pathData);

WPF Adding Path to ContentControl Doesn't Work At Runtime

You are setting the Width, Height, MinHeight, MinWidth, Canvas.Top and Canvas.Left properties in your code but not in your XAML. That's the difference. Try to remove these lines:

var contentGeomControl = new ContentControl();
var streamGeometry = StreamGeometry.Parse("M150,300 L300,300 A150,150 0 0 0 256,194 z");
var path = new Path { Data = streamGeometry, Fill = Brushes.Wheat, IsHitTestVisible = false };
var borderGeom = new Border { Background = Brushes.Transparent, VerticalAlignment = VerticalAlignment.Stretch, HorizontalAlignment = HorizontalAlignment.Stretch };
borderGeom.Child = path;
contentGeomControl.Content = borderGeom;
canvas.Children.Add(contentGeomControl);

Then you should see the same results.

Draw Figure as shown in this Image using Code

Whilst you can create this shape by adding and subtracting primitives (ellipses, rectangles, etc), for full flexibility, you are after the Path class

Using the values from your xaml example, it would look like this:

Path path = new Path();
path.Data = Geometry.Parse("M 100,200 C 100,25 400,350 400,175 H 280");

However, you can combine PathFigures to create more advanced shapes programmatically.

Define the path data from code behind in silverlight

From Codebehind :

Path orangePath = new Path();

PathFigure pathFigure = new PathFigure();

pathFigure.StartPoint = new Point(250, 40);

LineSegment lineSegment1 = new LineSegment();
lineSegment1.Point = new Point(200, 20);
pathFigure.Segments.Add(lineSegment1);

LineSegment lineSegment2 = new LineSegment();
lineSegment2.Point = new Point(200, 60);
pathFigure.Segments.Add(lineSegment2);

PathGeometry pathGeometry = new PathGeometry();
pathGeometry.Figures = new PathFigureCollection();

pathGeometry.Figures.Add(pathFigure);

orangePath.Data = pathGeometry;

Edit :

//we should have to set this true to draw the line from lineSegment2 to the start point

pathFigure.IsClosed = true;

Convert Geometry/Path to Minilanguage String?

Edit: Looking at this just now i thought that there should be a class called GeometryConverter which should be able to do this, and indeed there is. Just create one of those and use ConvertToString on the geometry you want to convert.


You can use the XamlWriter class to output objects as XAML, geometry will automatically be reduced to the mini-language.

e.g. if this is your input:

<DrawingImage x:Name="segmentsDrawing">
<DrawingImage.Drawing>
<DrawingGroup>

<GeometryDrawing Brush="Red">
<GeometryDrawing.Pen>
<Pen Brush="Black" />
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<PathGeometry>
<PathFigure StartPoint="100,100">
<PathFigure.Segments>
<LineSegment Point="100,0"/>
<ArcSegment Point="186.6,150" SweepDirection="Clockwise" Size="100,100"/>
<LineSegment Point="100,100"/>
</PathFigure.Segments>
</PathFigure>
</PathGeometry>
</GeometryDrawing.Geometry>
</GeometryDrawing>

<GeometryDrawing Brush="Blue">
<GeometryDrawing.Pen>
<Pen Brush="Black"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<PathGeometry>
<PathFigure StartPoint="100,100">
<PathFigure.Segments>
<LineSegment Point="186.6,150"/>
<ArcSegment Point="13.4,150" SweepDirection="Clockwise" Size="100,100"/>
<LineSegment Point="100,100"/>
</PathFigure.Segments>
</PathFigure>
</PathGeometry>
</GeometryDrawing.Geometry>
</GeometryDrawing>

<GeometryDrawing Brush="Green">
<GeometryDrawing.Pen>
<Pen Brush="Black"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<PathGeometry>
<PathFigure StartPoint="100,100">
<PathFigure.Segments>
<LineSegment Point="13.4,150"/>
<ArcSegment Point="100,0" SweepDirection="Clockwise" Size="100,100"/>
<LineSegment Point="100,100"/>
</PathFigure.Segments>
</PathFigure>
</PathGeometry>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>

...and you serialize it...

XmlTextWriter writer = new XmlTextWriter(@"C:\Users\Public\Test.xml", new UTF8Encoding());
writer.Formatting = Formatting.Indented;
writer.Indentation = 1;
writer.IndentChar = '\t';
XamlWriter.Save(segmentsDrawing, writer);

...you get the following:

<DrawingImage xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<DrawingImage.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="#FFFF0000">
<GeometryDrawing.Pen>
<Pen Brush="#FF000000" />
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<PathGeometry Figures="M100,100L100,0A100,100,0,0,1,186.6,150L100,100" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FF0000FF">
<GeometryDrawing.Pen>
<Pen Brush="#FF000000" />
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<PathGeometry Figures="M100,100L186.6,150A100,100,0,0,1,13.4,150L100,100" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FF008000">
<GeometryDrawing.Pen>
<Pen Brush="#FF000000" />
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<PathGeometry Figures="M100,100L13.4,150A100,100,0,0,1,100,0L100,100" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup.Children>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>

All the PathGeometry is now in mini-language. If you want to use this right away in your application i suppose you could write it to a MemoryStream and get the data from it by creating a XmlDocument from it.



Related Topics



Leave a reply



Submit