Rendering sharp lines in WPF - c#

If I render the following:
<Grid>
<Canvas SnapsToDevicePixels="True">
<Path Fill="#FF000000" SnapsToDevicePixels="True" Data="M 0.00,0.00 L 2.50,0.00 0.00,10.00 " />
<Path Fill="#FF260014" SnapsToDevicePixels="True" Data="M 2.50,0.00 L 7.50,0.00 2.50,10.00 0.00,10.00 " />
<Canvas.RenderTransform>
<ScaleTransform ScaleX="{Binding ElementName=slider,Path=Value}" ScaleY="{Binding ElementName=slider,Path=Value}" />
</Canvas.RenderTransform>
</Canvas>
<Slider x:Name="slider" Minimum="0" Maximum="50" Value="30"/>
</Grid>
I get this result (Kaxaml):
Notice the thin white line between the two shapes. I searched around and found out this has to do with pixel alignment. I would expect that settings SnapsToDevicePixels="True" would be enough to get rid of the line, but this doesn't work!
Any ideas how to get rid of the white line?

Try turning edge aliasing on with RenderOptions, like this (see Grid properties)
<Grid RenderOptions.EdgeMode="Aliased">
<Canvas SnapsToDevicePixels="True">
<Path Fill="#FF000000" SnapsToDevicePixels="True" Data="M 0.00,0.00 L 2.50,0.00 0.00,10.00 " />
<Path Fill="#FF260014" SnapsToDevicePixels="True" Data="M 2.50,0.00 L 7.50,0.00 2.50,10.00 0.00,10.00 " />
<Canvas.RenderTransform>
<ScaleTransform ScaleX="{Binding ElementName=slider,Path=Value}" ScaleY="{Binding ElementName=slider,Path=Value}" />
</Canvas.RenderTransform>
</Canvas>
<Slider x:Name="slider" Minimum="0" Maximum="50" Value="30"/>
</Grid>

Remember that SnapsToDevicePixels only controls that individual points do not lie on fractional pixel values. For horizontal and vertical lines this is most easily observed. In your case you are seeing an entirely different problem. The edges of your shapes are anti-aliased and therefore blended with the background. Since your shapes are exactly adjacent to each other both will be blended with the white background of the window. You can try putting one shape behind the other instead:
<Canvas>
<Path Fill="#FF000000" Data="M 0.00,0.00 L 7.50,0.00 2.50,10.00 0.00,10.00 " />
<Path Fill="#FF260014" Data="M 2.50,0.00 L 7.50,0.00 2.50,10.00 0.00,10.00 " />
<Canvas.RenderTransform>
<ScaleTransform ScaleX="{Binding ElementName=slider,Path=Value}" ScaleY="{Binding ElementName=slider,Path=Value}" />
</Canvas.RenderTransform>
</Canvas>
which should render correctly. You see similar rendering errors in many vector file formats that render primarily to screen, such as SVG.
The other option would be to turn off anti-aliasing but that will make your edges jaggy which may not be what you want (anti-aliasing turned off in the upper half):

Related

making a Question mark in WPF

I am using the expression Blender 2010 draw in WPF and I am trying to make a question mark. This is what I have so far and it looks bad:
<ed:Arc Canvas.Left="33" Width="28" Height="24" Canvas.Top="22" ArcThickness="6" StartAngle="-45" EndAngle="140" Stretch="None" Fill ="Red" />
<ed:Arc Canvas.Left="45" Width="28" Height="26" Canvas.Top="37" ArcThickness="6" StartAngle="90" EndAngle="180" Stretch="None" Fill ="Red" RenderTransformOrigin="0.498,0.458" >
<ed:Arc.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-179.625"/>
<TranslateTransform X="0.104" Y="1.427"/>
</TransformGroup>
</ed:Arc.RenderTransform>
</ed:Arc>
<Rectangle Canvas.Left="46" Canvas.Top="46" Width="6" Height="19" Stretch="Fill" Fill="Red" />
<Ellipse Canvas.Left="46" Width="6" Height="6" Canvas.Bottom="20" Fill="Red" Canvas.Top="70" RenderTransformOrigin="-0.477,-0.363" />
[enter image description here][1]
Updated: I just tried this :
<Path x:Name="Information" Canvas.Left="25" Canvas.Top="25" Stretch="Fill" Width="50" Height="50" Data="M9,89a81,81 0 1,1 0,2zm51-14c0-13 1-19 8-26c7-9 18-10 28-8c10,2 22,12 22,26c0,14-11,19-15,22c-3,3-5,6-5,9v22m0,12v16">
<Path.Fill>
<SolidColorBrush Color="Lime"/>
</Path.Fill>
</Path>
but it still look bad really bad[enter image description here][2]
please see up picture.
I got the information for the Sgv from
https://commons.m.wikimedia.org/wiki/Category:SVG_Question_marks
[1]: https://i.stack.imgur.com/A9X6A.png
[2]: https://i.stack.imgur.com/HKY6e.png
Looks like you are wanting to set up using paths in your WPF project.
Here is one example of doing this. There are many.
You can get your paths for example from Material Designs just click on an icon and then look at the SVG or XAML canvas where they have the Path.Data information.
For example below I have copied the data for a question mark and added it to a Viewbox. These ViewBox elements you can have in your Window.Resources or in a Resource file.
<Viewbox x:Key="questionMark">
<Canvas Width="512"
Height="512">
<Canvas.RenderTransform>
<TranslateTransform X="0"
Y="0" />
</Canvas.RenderTransform>
<Canvas.Resources />
<Canvas>
<Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Fill="Black"
Opacity="1.00">
<Path.Data>
<PathGeometry Figures="M10,19H13V22H10V19M12,2C17.35,2.22 19.68,7.62 16.5,11.67C15.67,12.67 14.33,13.33 13.67,14.17C13,15 13,16 13,17H10C10,15.33 10,13.92 10.67,12.92C11.33,11.92 12.67,11.33 13.5,10.67C15.92,8.43 15.32,5.26 12,5A3,3 0 0,0 9,8H6A6,6 0 0,1 12,2Z"
FillRule="NonZero" />
</Path.Data>
</Path>
</Canvas>
</Canvas>
</Viewbox>
To Use it you just add a Grid;
<Grid Background="Yellow" Width="50" Height="50">
<Grid.OpacityMask>
<VisualBrush Visual="{StaticResource questionMark}" />
</Grid.OpacityMask>
</Grid>
Result looks like this;

How to bind PathGeometry objects in MVVM

Imagine an application where the user can type in some text and based on the text input different symbols are shown on an image.
I am looking for a way generate a list of Path objects and bind this list in XAML to show the path objects on top of another path-image.
I.e. I have a simple image of a house, the user type in text like:
"ball on roof, flower in window, shovel in garden"
In the ViewModel I will analyze this text and generate a path Circle for the ball, a path Star for the flower and a path Square for the shovel.
I think these objects should be put in a List and in XAML bind to this list.
The "house" is drawn like this:
<Border Grid.Column="1" CornerRadius="10" BorderBrush="Black" BorderThickness="0.3" Margin="5,0,0,0" Grid.RowSpan="2" Padding="5">
<Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Stretch="Uniform">
<Grid RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="-1" ScaleX="1"/>
<SkewTransform AngleY="0" AngleX="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform/>
</TransformGroup>
</Grid.RenderTransform>
<Path Fill="Black" Data="{StaticResource Path1}"/>
<Path Fill="Black" Data="{StaticResource Path2}"/>
<Path Fill="Black" Data="{StaticResource Path3}"/>
<Path Fill="Black" Data="{StaticResource Path4}"/>
...
</Grid>
</Viewbox>
</Border>
After the all the "Path" I imagine I would use a CombinedGeometry and bind to the VM List. But I am not sure about this part.

Shape with slanted lines as background

Is possible to draw a Shape that has a background made by slanted lines?
An example with Rectangle (sorry for the image quality):
And if i want dashed lines or change the line properties (stroke, thickness..)?
You can use solution from this article http://mark-dot-net.blogspot.com/2007/06/creating-hatched-patterned-brush-in-wpf.html
<VisualBrush
x:Key="HatchBrush"
TileMode="Tile" Viewport="0,0,10,10"
ViewportUnits="Absolute" Viewbox="0,0,10,10"
ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Canvas>
<Rectangle Fill="Azure" Width="10" Height="10" />
<Path Stroke="Purple" Data="M 0 0 l 10 10" />
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
Just change the parameters etc. to fit your application
Usage:
<Rectangle Width="80" Height="40"
Fill="{StaticResource HatchBrush}"/>
Does this help: [WPF, C#: Draw a line onto existing bitmap in image control] or http://msdn.microsoft.com/en-us/library/ms747393.aspx

One circle and line inside it with radius 56

How to draw line inside circle, line will be visible only inside circle and I need to have control on line angel. Let say one circle and line inside it with angel 56. How to do this in C# WPF.
Just put an Ellipse and a Line in a Panel that lets them draw on top of each other (such as a Grid), and adjust the parameters to whatever you want.
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.LayoutTransform>
<RotateTransform Angle="56" CenterX="28" CenterY="28"/>
</Grid.LayoutTransform>
<Ellipse Height="56" Width="56" Stroke="Red" StrokeThickness="2" />
<Line X1="1" X2="55" Y1="28" Y2="28" Stroke="Red" StrokeThickness="2" />
</Grid>
If you want to do it in XAML, do it like this:
<Line X1="1" X2="55" Y1="28" Y2="28" Stroke="Red" StrokeThickness="2" >
<Line.LayoutTransform>
<RotateTransform Angle="56" CenterX="50" CenterY="50"/>
</Line.LayoutTransform>
</Line>
If you read through the respective overviews you should be able to manage: Geometry & Shapes

How can I get geometry information in C# from an XAML object?

given the following XAML code:
<Canvas Name="MainView">
<Canvas Name="TriangleElement" Width="50" Height="50" Canvas.Left="110" Canvas.Top="100">
<Canvas.RenderTransform>
<RotateTransform CenterX="25" CenterY="25" Angle="0" />
</Canvas.RenderTransform>
<Path Stroke="#FF009600" StrokeThickness="1" Fill="#FF68E168">
<Path.Data>
M 0,0 L 50,0 50,50 Z
</Path.Data>
</Path>
</Canvas>
<Canvas Name="SquareElement" Width="50" Height="50" Canvas.Left="170" Canvas.Top="100">
<Canvas.RenderTransform>
<RotateTransform CenterX="25" CenterY="25" Angle="0" />
</Canvas.RenderTransform>
<Path Stroke="#FF005DFF" StrokeThickness="1" Fill="#FF98D0F8">
<Path.Data>M 0,0 L 50,0 50,50 0,50 Z</Path.Data>
</Path>
</Canvas>
</Canvas>
How can I get the path data / geometry information in c# without naming it in the XAML? In the past I have created several UserControl's, created an interface to the objects, and pulled the info based on the Path name. In my current case I cannot use this approach.
Not sure if I understand the question, but can't you use
((Path)TriangleElement.Children[0]).Data
And what are those Canvas elements for? They don't seem to be doing anything.
Why not:
<Path Name="SquareElement" Width="50" Height="50" Stroke="#FF005DFF" StrokeThickness="1" Fill="#FF98D0F8">
<Path.RenderTransform>
<RotateTransform CenterX="25" CenterY="25" Angle="60" />
</Path.RenderTransform>
<Path.Data>M 0,0 L 50,0 50,50 0,50 Z</Path.Data>
</Path>
Then you can get straight to your paths by name.

Categories

Resources