I have a button style where I have some Path seth in Content property. That is working fine until I display a second instance of this button. I am getting an exception
Specified element is already the logical child of another element. Disconnect it first.
Other posts like this:
Error "Specified element is already the logical child of another element"?
led me to a solution that I need to transfer Content to ContentTemplate.
<Viewbox>
<Grid Margin="0,0,30,30">
<Path Fill="#FFFFFFFF">
<Path.Data>
<PathGeometry Figures="m 13.123027 65.796864 0 81.448876 133.750213 0 0 -133.778725 -67.192062 0 z" FillRule="NonZero"/>
</Path.Data>
</Path>
<Path Fill="{StaticResource DataCRUDIconBrush}">
<Path.Data>
<PathGeometry Figures="M 79.624708 0.36218262 0 62.950511 l 0 97.411669 160 0 0 -159.99999738 -80.375292 0 z m 2.28303 16.89635038 61.172792 0 0 126.207297 -126.161061 0 0 -76.829978 0.187646 -0.156158 64.800623 0 0 -49.221161 z" FillRule="NonZero"/>
</Path.Data>
</Path>
<Path Fill="#FFFFFFFF">
<Path.Data>
<PathGeometry Figures="m 13.123027 65.796864 0 81.448876 133.750213 0 0 -133.778725 -67.192062 0 z" FillRule="NonZero"/>
</Path.Data>
<Path.RenderTransform>
<TranslateTransform X="30" Y="30"/>
</Path.RenderTransform>
</Path>
<Path Fill="{StaticResource DataCRUDIconBrush}">
<Path.Data>
<PathGeometry Figures="M 79.624708 0.36218262 0 62.950511 l 0 97.411669 160 0 0 -159.99999738 -80.375292 0 z m 2.28303 16.89635038 61.172792 0 0 126.207297 -126.161061 0 0 -76.829978 0.187646 -0.156158 64.800623 0 0 -49.221161 z" FillRule="NonZero"/>
</Path.Data>
<Path.RenderTransform>
<TranslateTransform X="30" Y="30"/>
</Path.RenderTransform>
</Path>
</Grid>
</Viewbox>
How can I translate this code to fit the ContentTemplate, without loosing the triggers I hava there?
<Setter.Value>
<ControlTemplate TargetType="Button">
....
<ContentPresenter x:Name="Content" Opacity="0.5" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" />
</ControlTemplate>
</Setter.Value>
I know your problem. You are using data binding for the ContentPresenter.Content property.
And in this case, you need to be sure, that your binding object is not a visual element. It is very important. Disconnection from logical tree is not a good solution (just 'bottle-necks', another words).
Content can contains only non-visual objects. All visual parts of your control should be in its ContentPresenter.ContentTemplate property and no another way.
Thus I think all your code with graphics should be placed in the ContentTemplate property. If you have troubles with it, please, share your entire sample and I try to help you, as much i can.
Related
I would like to draw a left and right arrows like the following up and bottom arrows:
//up arrow
<Path Data="m 4 14 4 0 0 -9 3 0 -5 -5 -5 5 3 0 z"
Fill="#571CB61C"
Stroke="#FF00B400"
StrokeThickness="1" />
//bottom arrow
<Path Data="m 3.5 0 4 0 0 8 3 0 -5 5 -5 -5 3 0 z"
Fill="#571CB61C"
Stroke="#FF00B400"
StrokeThickness="1" />
Any help will be appreciated
Here is a way so you don't have to rely on anyone in the future
1) first download Inkscape then install it then go to flaticon.com.
2) second search for the icon that you like then download its svg format.
3) now, open the icon in Inkscape and after you select it.
4) go to the menu bar then Path -> Object to Path
5) then go to File -> Save As then change the save type to .xaml
all what you have to do now is copy the results from the .xaml file and paste it in your app.
here is a sample of my results using the following icons left arrow icon, right arrow icon
<!--thin left arrow-->
<Path Data="M 401.166 478.097 113.178 245.004 401.166 11.903 391.536 0 88.834 245.004 391.536 490 Z" Fill="Black" Stretch="Fill" Height="20" Width="10"/>
<!--thick left arrow-->
<Path Data="M 410.312 454.729 151.767 244.996 410.312 35.271 381.693 0 79.688 244.996 381.693 490 Z" Fill="Black" Stretch="Fill" Height="20" Width="10"/>
<!--thin right arrow-->
<Path Data="M 96.536 490 403.019 244.996 96.536 0 86.981 11.962 378.496 244.996 86.981 478.038 Z" Fill="Black" Stretch="Fill" Height="20" Width="10"/>
<!--thick right arrow-->
<Path Data="M 106.601 490 412.15 245.004 106.601 0 77.85 35.856 338.702 245.004 77.85 454.159 Z" Fill="Black" Stretch="Fill" Height="20" Width="10"/>
PS: i believe this can work on any svg icon.
I'm using the arrows in chart with zoom function and I need them to be precise, here are the final arrows:
<!-- Left Arrow -->
<Path
HorizontalAlignment="Center"
Data="m 290 10 5 -5 0 2.5 8 0 0 4 -8 0 0 3 z"
Fill="#571CB61C"
Stroke="#FF00B400"
StrokeThickness="1" />
<!-- Right Arrow -->
<Path
HorizontalAlignment="Center"
Data="m 4 14 4 0 0 -9 3 0 -5 -5 -5 5 3 0 z"
Fill="#571CB61C"
Stroke="#FF00B400"
StrokeThickness="1">
<Path.RenderTransform>
<RotateTransform Angle="90" CenterX="2" CenterY="8" />
</Path.RenderTransform>
</Path>
it is quite easy and it is explained here :
https://wpf.2000things.com/tag/streamgeometry/
https://learn.microsoft.com/it-it/dotnet/framework/wpf/graphics-multimedia/path-markup-syntax
I'm looking to create the following shape in XAML with System.Windows.Shapes.Path
(The image is a bit rough but demonstrates the curved corners in the top left and right and the curved bottom image).
So far I have the bottom curve with the following:
<Path Data="M0,0 L300,0 L300,40.768158 L296.83832,41.189522 C253.5976,46.794456 203.45944,50.000004 150,50.000004 C96.540565,50.000004 46.402409,46.794456 3.1617098,41.189522 L0,40.768158" ... />
But I am unsure how to get the top corners to be rounded with this.
You can use elliptical arcs (class ArcSegment) in your Path geometry:
<Path Fill="Black"
Data="M0,20 A20,20 0 0 1 20,0 L280,0 A20,20 0 0 1 300,20 L300,150 A150,75 0 0 1 0,150 Z"/>
Alternatively you could use a CombinedGeometry like this:
<Path Fill="Black">
<Path.Data>
<CombinedGeometry GeometryCombineMode="Union">
<CombinedGeometry.Geometry1>
<RectangleGeometry Rect="0,0,300,170" RadiusX="20" RadiusY="20"/>
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<EllipseGeometry Center="150,150" RadiusX="150" RadiusY="75"/>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</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.