Using path markup syntax, you can easily create Paths with custom shapes like a diamond:
<Path Data="M 0,5 L 5,0 L 10,5 L 5,10 Z" />
Is it possible to use this syntax in a PathGeometry? Per the link above (which is for WPF and not Silverlight), I tried using PathGeometry.Figures:
<local:SomeControl>
<local:SomeControl.Geometry>
<PathGeometry Figures="M 0,5 L 5,0 L 10,5 L 5,10 Z" />
</local:SomeControl.Geometry>
</local:SomeControl>
but this throws a XamlParseException
failed to create a 'PathGeometry.Figures' from the text 'M 0,5 L 5,0 L 10,5 L 5,10 Z'
Do I really need to use the extended form below, or is there some way to use the short string?
<PathGeometry>
<PathFigure StartPoint="0,5" IsClosed="True" IsFilled="True">
<LineSegment Point="5,0" />
<LineSegment Point="10,5" />
<LineSegment Point="5,10" />
</PathFigure>
</PathGeometry>
I just noticed that the Blend SDK has a ConvertToPathGeometry helper method. So it would be easy to create an IValueConverter using this:
return GeometryHelper.ConvertToPathGeometry((string)parameter);
And then the Geometry could be set to a PathGeometry instance like this:
<local:SomeControl Geometry="{Binding ConverterParameter='M 0,5 L 5,0 L 10,5 L 5,10 Z',
Converter={StaticResource PathGeometryConverter}}"
/>
Related
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>
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>
In my WPF multitouch application, I want to check whether a Path is overlapping another Path.
How can I do this? I have found different solutions on the Internet, but none is working, because of the combination of requirements:
2 Paths of irregular shape (so Bounds are not working: no Rect)
On the Paths a MatrixTransform is applied (because of Manipulation events)
The Paths can be rotated and scaled (using the MatrixTransform)
The RenderTransformOrigin is 0.5, 0.5
How can I do this?
Example: in this example the blue and red star are overlapping, the red and the green are not.
<Window x:Class="WPFTest.OtherWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="OtherWindow" Height="300" Width="300" >
<Canvas >
<Path x:Name="path1" Data="M17,0 L23,11 34,13 27,21 28,32 18,24 8,30 9,19 0,11 13,11 z" Fill="#99FF0000" Stroke="Black" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<MatrixTransform Matrix="1,0,0,1,50,50"/>
</Path.RenderTransform>
</Path>
<Path x:Name="path2" Data="M17,0 L23,11 34,13 27,21 28,32 18,24 8,30 9,19 0,11 13,11 z" Fill="#990000FF" Stroke="Black" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<MatrixTransform Matrix="0.777817459305202,0.777817459305202,-0.777817459305202,0.777817459305202,35,45"/>
</Path.RenderTransform>
</Path>
<Path x:Name="path3" Data="M17,0 L23,11 34,13 27,21 28,32 18,24 8,30 9,19 0,11 13,11 z" Fill="#9900FF00" Stroke="Black" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<MatrixTransform Matrix="0.777817459305202,0.777817459305202,-0.777817459305202,0.777817459305202,82,55"/>
</Path.RenderTransform>
</Path>
</Canvas>
How can I check this from code behind?
Thanks,
Jim
If it is acceptable, you may use transformed geometries for Path.Data instead of (render-)transformed Paths (with the drawback of course that their stroke won't be scaled).
Once you use such transformed geometries, you can determine their mutual intersection by Geometry.FillContainsWithDetail, which gives you an enum value for the kind of intersection.
Your XAML might look like the following. Note that because Geometry does not have something like a transform origin, I modified your geometry so that the coordinate origin lies in its center. I also added the resulting offset to the MatrixTransform offset values.
<Canvas>
<Path Name="redStar" Fill="#99FF0000" Stroke="Black">
<Path.Data>
<PathGeometry Figures="M0,-16 L6,-5 17,-3 10,5 11,16 1,8 -9,14 -8,3 -17,-5 -4,-5 z">
<PathGeometry.Transform>
<MatrixTransform Matrix="1,0,0,1,67,66"/>
</PathGeometry.Transform>
</PathGeometry>
</Path.Data>
</Path>
<Path Name="blueStar" Fill="#990000FF" Stroke="Black">
<Path.Data>
<PathGeometry Figures="M0,-16 L6,-5 17,-3 10,5 11,16 1,8 -9,14 -8,3 -17,-5 -4,-5 z">
<PathGeometry.Transform>
<MatrixTransform Matrix="0.777817459305202,0.777817459305202,-0.777817459305202,0.777817459305202,52,61"/>
</PathGeometry.Transform>
</PathGeometry>
</Path.Data>
</Path>
<Path Name="greenStar" Fill="#9900FF00" Stroke="Black">
<Path.Data>
<PathGeometry Figures="M0,-16 L6,-5 17,-3 10,5 11,16 1,8 -9,14 -8,3 -17,-5 -4,-5 z">
<PathGeometry.Transform>
<MatrixTransform Matrix="0.777817459305202,0.777817459305202,-0.777817459305202,0.777817459305202,99,71"/>
</PathGeometry.Transform>
</PathGeometry>
</Path.Data>
</Path>
</Canvas>
The following code will determine the intersections:
Geometry redGeometry = redStar.Data;
Geometry blueGeometry = blueStar.Data;
Geometry greenGeometry = greenStar.Data;
Trace.TraceInformation("red/blue intersection: {0}", redGeometry.FillContainsWithDetail(blueGeometry));
Trace.TraceInformation("blue/green intersection: {0}", blueGeometry.FillContainsWithDetail(greenGeometry));
Trace.TraceInformation("green/red intersection: {0}", greenGeometry.FillContainsWithDetail(redGeometry));
redGeometry.Transform = new MatrixTransform(1, 0, 0, 1, 70, 90);
Trace.TraceInformation("red/blue intersection: {0}", redGeometry.FillContainsWithDetail(blueGeometry));
I converted an Adobe Illustrator file to .xaml using Expression Design 4. Now want to take the ControlTemplate that was generated and use this as as an ImageProperty in the LargeImageSource or SmallImageSource in the MS RibbonControl.RibbonButton. There is an images resource dictionary that has been created and the following code is placed there:
<Viewbox x:Uid="Viewbox_1" Stretch="Uniform">
<Canvas x:Uid="Canvas_1" Width="224" Height="224" Clip="F1 M 0,0L 224,0L 224,224L 0,224L 0,0">
<Canvas x:Uid="Layer_1" x:Name="Layer_1" Width="224" Height="224" Canvas.Left="0" Canvas.Top="0"/>
<Canvas x:Uid="Layer_1_0" x:Name="Layer_1_0" Width="224" Height="224" Canvas.Left="0" Canvas.Top="0">
<Path x:Uid="Path" x:Name="Path" Width="224" Height="224" Canvas.Left="0" Canvas.Top="0.00012207" Stretch="Fill" Data="F1 M 4.8,0.00012207C 2.16,0.00012207 0,2.1468 0,4.77348L 0,219.228C 0,221.853 2.16,224 4.8,224L 219.201,224C 221.84,224 224,221.853 224,219.229L 224,4.77348C 224,2.1468 221.84,0.00012207 219.201,0.00012207L 4.8,0.00012207 Z ">
<Path.Fill>
<LinearGradientBrush x:Uid="LinearGradientBrush_1" StartPoint="0.500003,1" EndPoint="0.500003,3.06538e-006">
<LinearGradientBrush.GradientStops>
<GradientStop x:Uid="GradientStop_1" Color="#FFFDEFB3" Offset="0"/>
<GradientStop x:Uid="GradientStop_2" Color="#FFF8E291" Offset="0.134848"/>
<GradientStop x:Uid="GradientStop_3" Color="#FFF4D570" Offset="0.5"/>
<GradientStop x:Uid="GradientStop_4" Color="#FFF8E291" Offset="0.865152"/>
<GradientStop x:Uid="GradientStop_5" Color="#FFFDEFB3" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Path.Fill>
</Path>
<Path x:Uid="Path_1" x:Name="Path_1" Width="226.667" Height="226.667" Canvas.Left="-1.33333" Canvas.Top="-1.33333" Stretch="Fill" StrokeThickness="2.66667" StrokeMiterLimit="2.75" Stroke="#FF666666" Data="F1 M 224,219.229C 224,221.853 221.84,224 219.2,224L 4.80134,224C 2.16,224 0,221.853 0,219.228L 0,4.77332C 0,2.14799 2.16,0 4.80134,0L 219.2,0C 221.84,0 224,2.14799 224,4.77332L 224,219.229 Z "/>
<Path x:Uid="Line" x:Name="Line" Width="206.112" Height="8" Canvas.Left="10.2715" Canvas.Top="164.591" Stretch="Fill" StrokeThickness="8" StrokeMiterLimit="2.75" Stroke="#FF2A3B8E" Data="F1 M 14.2715,168.591L 212.383,168.591"/>
<Path x:Uid="Path_2" x:Name="Path_2" Width="42.3867" Height="42.3853" Canvas.Left="48.3855" Canvas.Top="147.399" Stretch="Fill" Fill="#FFCF1F3C" Data="F1 M 90.7721,168.594C 90.7721,180.295 81.2868,189.785 69.5775,189.785C 57.8735,189.785 48.3855,180.295 48.3855,168.594C 48.3855,156.887 57.8735,147.399 69.5775,147.399C 81.2868,147.399 90.7721,156.887 90.7721,168.594 Z "/>
<Path x:Uid="Path_3" x:Name="Path_3" Width="42.3867" Height="42.384" Canvas.Left="133.555" Canvas.Top="147.399" Stretch="Fill" Fill="#FF1B75BB" Data="F1 M 175.941,168.594C 175.941,180.295 166.456,189.783 154.747,189.783C 143.043,189.783 133.555,180.295 133.555,168.594C 133.555,156.887 143.043,147.399 154.747,147.399C 166.456,147.399 175.941,156.887 175.941,168.594 Z "/>
<Path x:Uid="Line_4" x:Name="Line_4" Width="68.1093" Height="10.6667" Canvas.Left="119.548" Canvas.Top="64.672" Stretch="Fill" StrokeThickness="10.6667" StrokeMiterLimit="2.75" Stroke="#FF00B6DD" Data="F1 M 124.881,70.0053L 182.324,70.0053"/>
<Path x:Uid="Line_5" x:Name="Line_5" Width="10.6667" Height="76.748" Canvas.Left="148.51" Canvas.Top="32.187" Stretch="Fill" StrokeThickness="10.6667" StrokeMiterLimit="2.75" Stroke="#FF00B6DD" Data="F1 M 153.844,103.602L 153.844,37.5204"/>
<Path x:Uid="Path_6" x:Name="Path_6" Width="35.5831" Height="28.2761" Canvas.Left="136.055" Canvas.Top="13.6534" Stretch="Fill" StrokeThickness="8" StrokeMiterLimit="2.75" Stroke="#FF00B6DD" Fill="#FF00B6DD" Data="F1 M 167.578,37.6095L 153.61,17.7814C 153.485,17.6081 153.286,17.6108 153.167,17.7895L 140.109,37.6041C 139.993,37.7828 140.07,37.9295 140.285,37.9295L 167.413,37.9295C 167.627,37.9295 167.702,37.7868 167.578,37.6095 Z "/>
<Path x:Uid="Path_7" x:Name="Path_7" Width="35.5846" Height="28.2777" Canvas.Left="135.783" Canvas.Top="98.1695" Stretch="Fill" StrokeThickness="8" StrokeMiterLimit="2.75" Stroke="#FF00B6DD" Fill="#FF00B6DD" Data="F1 M 167.137,102.169L 140.01,102.169C 139.794,102.169 139.718,102.315 139.843,102.489L 153.813,122.315C 153.935,122.493 154.134,122.491 154.253,122.309L 167.313,102.497C 167.431,102.317 167.35,102.169 167.137,102.169 Z "/>
<Path x:Uid="Path_8" x:Name="Path_8" Width="28.2794" Height="35.5851" Canvas.Left="180.031" Canvas.Top="52.7121" Stretch="Fill" StrokeThickness="8" StrokeMiterLimit="2.75" Stroke="#FF00B6DD" Fill="#FF00B6DD" Data="F1 M 184.359,56.7671C 184.182,56.6484 184.031,56.7284 184.031,56.9431L 184.031,84.0724C 184.031,84.2844 184.174,84.3617 184.351,84.2377L 204.179,70.2684C 204.357,70.1431 204.354,69.9444 204.174,69.8284L 184.359,56.7671 Z "/>
<Path x:Uid="Path_9" x:Name="Path_9" Width="28.2777" Height="35.5834" Canvas.Left="100.22" Canvas.Top="51.6494" Stretch="Fill" StrokeThickness="8" StrokeMiterLimit="2.75" Stroke="#FF00B6DD" Fill="#FF00B6DD" Data="F1 M 124.169,83.1772C 124.349,83.2972 124.497,83.2159 124.497,83.0025L 124.497,55.8745C 124.497,55.6599 124.355,55.5865 124.176,55.7079L 104.348,69.6759C 104.175,69.8025 104.176,69.9999 104.357,70.1172L 124.169,83.1772 Z "/>
</Canvas>
</Canvas>
</Viewbox>
Currently we are using bitmaps with png files as the image source, but now want to use the above xaml files.
Thank you in advance for any help.
Bill
Use Expression Blend to convert this to a DrawingImage:
Place this XAML in some file where you can see it in the designer.
Select the Viewbox.
Click Tools > Make Brush Resource > Make Drawing Brush.
From the created brush, extract the root DrawingGroup and give it some key.
Create a DrawingImage and assign the Drawing property to the above DrawingGroup.
Assign the DrawingImage to the {Large, Small}ImageSource property.
In WPF, is it posible to encode this into a single Path tag with a Data attribute?
<Path Stroke="White" StrokeThickness="2">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="7,32">
<ArcSegment Point="7,18" Size="200,50" RotationAngle="0" IsLargeArc="False" />
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
Something like this: (only this is a completely wrong shape)
<Path Stroke="DarkGoldenRod" StrokeThickness="3"
Data="M 100,200 C 100,25 400,350 400,175 H 280" />
Try this:
<Path Data="M 7,32 A 200,50 0 0 0 7,18" .../>
See also Path Markup Syntax.