WPF does not align path properly at run time - wpf

I have a 16x16 vector drawn up in Expression Design that I imported in to Blend and used in a control template. Here's the XAML:
<ControlTemplate x:Key="CircularButtonTemplate" TargetType="{x:Type Button}">
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="Layer_1" Width="16" Height="16" Canvas.Left="0" Canvas.Top="0">
<Ellipse x:Name="_circle" Width="15.0208" Height="15.0208" Canvas.Left="0.375033" Canvas.Top="0.479169" Stretch="Fill" Fill="#FF666666" />
<Path x:Name="_darkShadow" Width="14.727" Height="14.686" Canvas.Left="0.232" Canvas.Top="0.357" StrokeThickness="3" StrokeLineJoin="Round" Stroke="Black" Data="M 2.02083,8.03473L 13.7501,8.03473M 7.84484,2.14584L 7.84484,13.8333"/>
<Path x:Name="_lightShadow" Width="14.727" Height="14.686" Canvas.Left="0.857" Canvas.Top="0.732" StrokeThickness="3" StrokeLineJoin="Round" Stroke="#FFABABAB" Data="M 2.02083,8.03473L 13.7501,8.03473M 7.84484,2.14584L 7.84484,13.8333"/>
<Path x:Name="_plus" Width="14.7292" Height="14.6875" Canvas.Left="0.520833" Canvas.Top="0.645836" StrokeThickness="3" StrokeLineJoin="Round" Stroke="#FFFFFFFF" Data="M 2.02083,8.03473L 13.7501,8.03473M 7.84484,2.14584L 7.84484,13.8333"/>
</Canvas>
While Blend and Exp Design shows image neatly, at run time, the + sign in the center does not align properly when applied to a button:
How do I fix this?

Try setting UseLayoutRounding="True" on the Canvas.

Just needed to tweak that generated code it gave you to give more defined values. Try this.
<Canvas x:Name="Layer_1" Width="16" Height="16" VerticalAlignment="Center" HorizontalAlignment="Center">
<Ellipse x:Name="_circle" Width="16" Height="16" Stretch="Fill" Fill="#FF666666" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Path x:Name="_darkShadow" Width="16" Height="16" StrokeThickness="3" Stroke="Black" Data="M 2.02083,8.03473L 13.7501,8.03473M 7.84484,2.14584L 7.84484,13.8333" HorizontalAlignment="Center" VerticalAlignment="Center" UseLayoutRounding="False" Canvas.Left="-0.5" Canvas.Top="-0.5"/>
<Path x:Name="_lightShadow" Width="16" Height="16" StrokeThickness="3" Stroke="#FFABABAB" Data="M 2.02083,8.03473L 13.7501,8.03473M 7.84484,2.14584L 7.84484,13.8333" Canvas.Left="-0.5" Canvas.Top="-0.5" Visibility="Collapsed"/>
<Path x:Name="_plus" Width="14" Height="14" StrokeThickness="3" Stroke="#FFFFFFFF" Data="M 2.02083,8.03473L 13.7501,8.03473M 7.84484,2.14584L 7.84484,13.8333" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Canvas>

Related

Converting SVG to XAML

I know this question has already been answered, as I have followed the instructions of these answers. I have a .SVG image of an icon, which I am trying to convert into useable XAML code, I am using my images like this;
<ControlTemplate x:Uid="ControlTemplate_9" x:Key="IconTemplate">
<Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Stretch="Uniform">
<Canvas Name="svg2" Width="24" Height="16" ToolTip="IconToolTip.">
<Canvas.RenderTransform>
<TranslateTransform X="0" Y="0"/>
</Canvas.RenderTransform>
<Canvas.Resources/>
<Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path16" Fill="#FFFCF0F0">
<Path.Data>
<PathGeometry Figures=" M 22.30" FillRule="NonZero"/>
</Path.Data>
</Path>
</Canvas>
</Viewbox>
</ControlTemplate>
When I picked up this system most of these were already provided, but my issue is adding more to it. When using programs such as Inkscape or printing to PDF and opening the .fpage file I am getting .XAML along the lines of -
<?xml version="1.0" encoding="UTF-8"?>
<!--This file is NOT compatible with Silverlight-->
<Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Stretch="Uniform">
<Canvas Name="svg2" Width="24" Height="16">
<Canvas.RenderTransform>
<TranslateTransform X="0" Y="0"/>
</Canvas.RenderTransform>
<Canvas.Resources/>
<!--Unknown tag: metadata-->
<!--Unknown tag: sodipodi:namedview-->
<Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="24" Height="16" RadiusX="4" RadiusY="4" Name="Rounded_Rectangle_1" Fill="#000000"/>
<Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="11" Canvas.Top="3" Width="2" Height="6" Name="rect9" Fill="#000000"/>
<Image xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="image11" Canvas.Left="11" Canvas.Top="11" Source="data:img/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAQAAAABazTCJAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfgCRoPHAwMuTLjAAAADElEQVQI12M4wHAAAAMEAYHFO6KpAAAAAElFTkSuQmCC" Width="2" Height="2"/>
</Canvas>
</Viewbox>
The latter will not compile and causes the program to crash. So my extension to the previous questions would be, how do I use the latter XAML in my codebase without directly having an image in the project folder or how do I convert this into useable path data.
What I have done and which is actually working perfectly is to remove all the part with xml:
<Viewbox Stretch="Uniform">
<Canvas Name="svg2" Width="24" Height="16">
<Canvas.RenderTransform>
<TranslateTransform X="0" Y="0"/>
</Canvas.RenderTransform>
<Canvas.Resources/>
<Rectangle Width="24" Height="16" RadiusX="4" RadiusY="4" Name="Rounded_Rectangle_1" Fill="#000000"/>
<Rectangle Canvas.Left="11" Canvas.Top="3" Width="2" Height="6" Name="rect9" Fill="#000000"/>
<Image Name="image11" Canvas.Left="11" Canvas.Top="11" Source="data:img/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAQAAAABazTCJAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfgCRoPHAwMuTLjAAAADElEQVQI12M4wHAAAAMEAYHFO6KpAAAAAElFTkSuQmCC" Width="2" Height="2"/>
</Canvas>
</Viewbox>
And I have added them to a ResourceDictionary, so they can be used in the whole project.
<Viewbox x:Key="MyIcon" x:Shared="False" Stretch="Uniform">
<Canvas Name="svg2" Width="24" Height="16">
<Canvas.RenderTransform>
<TranslateTransform X="0" Y="0"/>
</Canvas.RenderTransform>
<Canvas.Resources/>
<Rectangle Width="24" Height="16" RadiusX="4" RadiusY="4" Name="Rounded_Rectangle_1" Fill="#000000"/>
<Rectangle Canvas.Left="11" Canvas.Top="3" Width="2" Height="6" Name="rect9" Fill="#000000"/>
<Image Name="image11" Canvas.Left="11" Canvas.Top="11" Source="data:img/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAQAAAABazTCJAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfgCRoPHAwMuTLjAAAADElEQVQI12M4wHAAAAMEAYHFO6KpAAAAAElFTkSuQmCC" Width="2" Height="2"/>
</Canvas>
</Viewbox>

combine elements on form

I've got two rectangles and an ellipse. How to combine them and use the same animation on new combined element?
<Rectangle Height="100" HorizontalAlignment="Left" Margin="220,235,0,0" Name="rectangle2" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="38" Fill="LightGreen" />
<Ellipse Height="23" HorizontalAlignment="Left" Margin="227,269,0,0" Name="ellipse1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="24" Fill="Yellow" />
<Ellipse Height="17" HorizontalAlignment="Left" Margin="12,266,0,0" Name="ellipse2" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="17" Fill="#FF58FF00" />
If you want fixed size elements, moved relative to each other, then place them in a canvas and use canvas coordinates to position them.
A canvas has a low overhead for rendering as it displays nothing but its child elements, in pixel offsets, and has no complex calculation of margins or rows.
The equivalent of your example is:
<Canvas HorizontalAlignment="Left" Margin="12,235,0,145" Width="246">
<Rectangle Height="100" x:Name="rectangle2" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="38" Fill="LightGreen" Canvas.Left="208" />
<Ellipse Height="23" x:Name="ellipse1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="24" Fill="Yellow" Canvas.Left="215" Canvas.Top="34" />
<Ellipse Height="17" x:Name="ellipse2" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="17" Fill="#FF58FF00" Canvas.Top="31" />
</Canvas>
Group into T:Panel.
Usually I'm grouping in Canvas first, then in Viewbox (Fill ot Fit) second.

How to leave margin between elements in the stack panel

I use the stack panel. It looks like every elements inside is stacking tightly. How to leave some margin between them.
Easiest way is to give each item it's own Margin
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Rectangle Fill="White" Stroke="Black" Width="100" Height="35" StrokeThickness="5" Margin="5,0,0,0"/>
<Rectangle Fill="White" Stroke="Black" StrokeThickness="5" Width="100" Height="35" Margin="5,0,0,0"/>
<Rectangle Fill="White" Stroke="Black" Width="100" Height="35" Margin="5,0,0,0" StrokeThickness="5"/>
</StackPanel>

Path with broken shadow effect

I hope that it is clear enough in the image, I have a triangle with shadow effect that doesn't look so good, seems to be broken somehow.
Any help will be greatly appreciated.
(Update: the rectangle and the path have to be separated)
XAML:
<Grid Height="50" Width="60" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="1" Stroke="Black" Fill="White">
<Rectangle.Effect>
<DropShadowEffect Opacity="0.5" ShadowDepth="4" BlurRadius="10" />
</Rectangle.Effect>
</Rectangle>
<Path Fill="White" Stretch="Fill" Stroke="Black" HorizontalAlignment="Left" Margin="0,15,-1,15"
Data="M44.386378,164.8791 L22.983157,171.42119 44.713478,176.58567" Width="23.167">
<Path.Effect>
<DropShadowEffect BlurRadius="10" Opacity="0.5" ShadowDepth="4" />
</Path.Effect>
</Path>
</Grid>
</Grid>
On your triangle:
Remove the Margin
Set the Path height explicitly ("22" is pretty close what you have there).
That should prevent the triangle's shadow from being clipped.
Here's the xaml for that:
<Grid Height="50" Width="60" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="1" Stroke="Black" Fill="White" >
<Rectangle.Effect>
<DropShadowEffect Opacity="0.5" ShadowDepth="4" BlurRadius="10" />
</Rectangle.Effect>
</Rectangle>
<Path Fill="White" Stretch="Fill" Stroke="Black" HorizontalAlignment="Left"
Data="M44.386378,164.8791 L22.983157,171.42119 44.713478,176.58567" Width="23.167" Height="22">
<Path.Effect>
<DropShadowEffect BlurRadius="10" Opacity="0.5" ShadowDepth="4" />
</Path.Effect>
</Path>
</Grid>
The problem is you have two separate elements each with a drop shadow. You cannot expect their shadows to join up nicely, the 'blur' is applied separately to each element. Try combining your rectangle and triangle into a single path. e.g.
<Path Fill="White" Stretch="Fill" Stroke="Black" HorizontalAlignment="Left" Margin="0,15,-1,15"
Data="M 0,0 L 100,0 L 100,400 L 0,400 L 0,300 L -50, 200 L 0, 100 L 0,0">
<Path.Effect>
<DropShadowEffect BlurRadius="10" Opacity="0.5" ShadowDepth="4" />
</Path.Effect>
</Path>

In pure XAML, is it possible to get a Line to align to part of a Grid?

Is it possible to create a Line in XAML (without any C# code behind) to align a line inside of a layout container such as a Grid?
I'd like to effectively have:
<Grid>
<Line StrokeThickness="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Stroke="Red"/>
</Grid>
I need to use StrokeDashArray and StrokeDashOffset, otherwise I would just use a Border control with the BorderThickness set to "0,0,0,1"...
Thanks for any ideas!
To elaborate on kanchirk's response, this works for me:
<Path StrokeThickness="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Data="M0,0 L1,0"
Stretch="Fill"
StrokeEndLineCap="Square"
StrokeStartLineCap="Square"
Stroke="Red"/>
You can also the same thing with a Line:
<Line StrokeThickness="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
X2="1"
Stretch="Fill"
StrokeEndLineCap="Square"
StrokeStartLineCap="Square"
Stroke="Red"/>
I think you need to use Path like this
<Grid x:Name="LayoutRoot" Background="White">
<Path Fill="Red" Stretch="Fill" Stroke="Black" StrokeDashArray="1" Height="4" Margin="8,0,7,7" VerticalAlignment="Bottom" UseLayoutRounding="False" Data="M8,127 L457,127" StrokeThickness="13"/>
</Grid>
Hope this Helps. Expression Blend is a must have for this kind of Challenges or even VS 2010 RC1 (For now)
How about this?
<Line x:Name="line"
StrokeThickness="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Stroke="Red"
X2="{Binding ActualWidth, ElementName=line, Mode=OneWay}"
Stretch="Fill"
StrokeStartLineCap="Square"
StrokeEndLineCap="Square"/>

Resources