How to group Paths in WPF? - wpf

I'm using paths to create a specific shape. What is the best way to group all the paths so I'll be able to use them later in another location without re-positioning the paths?
Any suggestions will be great, thank you!

If the question is about a complex shape with just one fill and stroke, an option would be to use just one Path instance with a PathGeometry with multiple Figures. See the following example from MSDN:
<Path Stroke="Black" StrokeThickness="1">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure IsClosed="True" StartPoint="10,100">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="100,100" />
<LineSegment Point="100,50" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
<PathFigure IsClosed="True" StartPoint="10,10">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="100,10" />
<LineSegment Point="100,40" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>

You can group then in a canvas and then just re-position your canvas.
Naming every path point would give you the ability to modify the shape....
You can create a new class called MyOwnShape that inherits the Canvas class, and then attach an event for every point of the canvas to drag and drop so the shape gets modified. You might also put your content inside a grill but you wont be able to position your shapes with that kind of precision.
If i understood corectly what you want to achive.Your class should looke like this
class MyOwnShapes : Canvas {
List<Path> myListOfPaths;
public void AddPath(Path myPath){
this.Children.Add(path);
myListOfPaths.Add(path), // this is used for your internal computation so it wont affect the effective drawin components.
}
I hope this example is good for you.
http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh465055.aspx
http://www.windowsphonegeek.com/tips/drawing-in-wp7-3-understanding-path-shapes

Related

Can you style individual segments of a Path?

I'm showing a series of data points where the first segment in the series is colored differently than all the other segments (image 1).
At the moment the first segment is a separate object than the other segments in the series, which are all a single Path comprised by PolyLineSegments.
You can see in the images that the mating surfaces between the first segment and the second (where the color changes) is not very clean, however it is rendered much nicer in the remaining cases (third image example).
Is it possible to alter the colors for individual segments? If so I could merge the standalone line into the PathSegmentCollection and I think that would resolve the rendering issue. But the various attributes such as Stroke are only available on the Path tag, not the subsidiary objects.
<Line
X1="{Binding LeadingCoordinate.Screen.X}"
Y1="{Binding LeadingCoordinate.Screen.Y}"
X2="{Binding Coordinates[0].Screen.X}"
Y2="{Binding Coordinates[0].Screen.Y}"
Stroke="Red"
StrokeThickness="5"
Opacity="0.25"
StrokeStartLineCap="Round"
StrokeEndLineCap="Flat"
/>
<Path
Stroke="Blue"
StrokeThickness="5"
Opacity="0.25"
StrokeStartLineCap="Round"
StrokeEndLineCap="Round"
StrokeLineJoin="Round"
>
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="{Binding ScreenPoints[0]}">
<PathFigure.Segments>
<PathSegmentCollection>
<PolyLineSegment Points="{Binding ScreenPoints}"/>
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>

XAML PathGeometry Relative Positioning (m not M)

I am trying to replicate a square I drew with (Path) by using (PathGeometry). I want to move this square around based on its starting position, and let the rest render relative to that. But I can't figure out how to replicate the "m" property of (Path.Data) this way, it does for some reason I don't get automagically use "M". Anyone that could educate me on how to fix this? Google does not really distinguish between "m" and "M".
Original Path (Square):
<Path Stroke="Red" Data="m 15 250 70 0 0 90 -70 0 z"></Path>
And this is the alternative I am trying to get to work (which apparently makes it easier to move the full square by binding the starting point to a value I control).
<Path Stroke="Black" StrokeThickness="1">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure IsClosed="True" StartPoint="15,250">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="70,0" />
<LineSegment Point="0,90" />
<LineSegment Point="-70,0" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>

How to make a reverse Path

I have this code:
<Path Stroke="Black" Margin="15">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="150,100">
<ArcSegment Size="50,50" Point="50,50" />
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
And the resulting Path is this:
I want to make the reverse Path:
But I want to make this without turn the StartPoint and the ArcSegment Point, because I need this Path to make a DoubleAnimationUsingPath (If I set StartPoint to 50,50 and the ArcSegmentPoint to 150,100, the figure is ok, but the animation goes in reverse mode).
The fix for this particular case is quite easy, simply set SweepDirection="Clockwise" on your ArcSegment. If this was just an example and not your actual use-case you might want to include more code (e.g. the Animation).
<Path Stroke="Black" Margin="15">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="150,100">
<ArcSegment SweepDirection="Clockwise" Size="50,50" Point="50,50" />
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
Just in case you need it, there is also a IsLargeArc setting that you could toggle once you reach a certain threshold (depends on your use-case).
Example Result:

WPF - Path Geometry...Is there a way to bind the Data Property?

I have a ControlTemplate that serves as a "Bubble" popup on the AdornerLayer of a given control.
It works fine but I need to be able to calculate where it should display (middle/ bottom).
Instead of:
<Path Stroke="Black" Fill="Black" Data="M 15 20 L 15 0 33 20" Margin="0 1 0 0"/>
I am looking for (obviously this won't work but it illustrates what I'm trying to accomplish:
<Path Stroke="Black" Fill="Black" Data="M {TemplateBinding Left} 20 L 15 0 33 20"/>
Can this be done with a ValueConverter? I just can't visualize a solution for some reason. I'm also open to alternatives.
Thanks for reading and if I can provide more info please just ask.
If you want a value converter that you can use to convert a string into the path data, you might like to try the universal value converter I wrote a while back.
Alternatively, to bind to a single property, you will have to expand your geometry by adding the various geometry objects into your XAML, rather than using the string shorthand. For example ...
<Path Stroke="Black" StrokeThickness="1">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure IsClosed="True" StartPoint="10,100">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="{Binding MyPropertyPath}" />
<LineSegment Point="100,50" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>

Silverlight - how to draw a line with an arc?

I am developing a small silverlight application (using siverlight 4 and c#). In my application I need to draw coordinates based on their X,Y. Then, I need to draw lines between some of the points, based on the connections between them. Since there can be several lines, and I cannot have them all intersecting each other (as it will turn this into a mess), I need to draw some of my lines with an arch.
So, What would be the best way to approach this issue?
Create my own x,y system - position elements in points and draw lines - If so How can I draw a line with an arch?
Use a ready control that provides similar capabilities? If so, what control?
Thank You!
Attached is a small image to illustrate my need (I am no big painter, sorry).
Take a look at drawing Bezier curves (MSDN Link) and learn about the different geometry types (MSDN Link)
Below is a code sample to get you started that will produce the following image:
<Canvas x:Name="LayoutRoot" Background="White">
<Path Stroke="Blue" StrokeThickness="2" >
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="50,50">
<PathFigure.Segments>
<PathSegmentCollection>
<BezierSegment
Point1="50,20"
Point2="120,170"
Point3="350,150"
/>
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
<Path Fill="Gold" Stroke="Black" StrokeThickness="1">
<Path.Data>
<EllipseGeometry Center="50,50" RadiusX="20" RadiusY="20" />
</Path.Data>
</Path>
<Path Fill="Gold" Stroke="Black" StrokeThickness="1">
<Path.Data>
<EllipseGeometry Center="350,150" RadiusX="20" RadiusY="20" />
</Path.Data>
</Path>
</Canvas>

Resources