How to make a custom shape with properties in WPF? - c#

How to create a custom shape in WPF? For example, I am trying to draw multiple symbols connected between each other on a cavas. I would need each symbol to change the color as well. How would I create let's say a custom shape that can change colors. Let's say the following two shapes I would like to make into one. how would I go to encapsulate them
<Ellipse x:Name="theEllipse"
Height="89"
Width="82"
Fill="Black"
Canvas.Left="32"
Canvas.Top="75" />
<Ellipse x:Name="theEllipse"
Height="89"
Width="82"
Fill="Black"
Canvas.Left="32"
Canvas.Top="75" />
The solution provided below does work with the ellipses however,
it does not work with the following figures:
<Line X1="10"
Y1="50"
X2="50"
Y2="50"
Stroke="Black"
StrokeThickness="2" />
<Line X1="15"
Y1="55"
X2="45"
Y2="55"
Stroke="Black"
StrokeThickness="2" />
<Line X1="20"
Y1="60"
X2="40"
Y2="60"
Stroke="Black"
StrokeThickness="2" />

You can do it in Blend.
Select the two ellipses/shapes in the Objects and Timeline window
Right-click on the selection
Go to Path -> Make compound path
Update 2017-04-10
If you want this operation to work with all shapes and lines, you have to make sure your elements are inside a Canvas, not a Grid or StackPanel. The parent container of the elements matters.
So in the case of the 3 lines, wrap them inside a Canvas and run the Make Compound Path operation again.
<Canvas>
<Line X1="10"
Y1="50"
X2="50"
Y2="50"
Stroke="Black"
StrokeThickness="2" />
<Line X1="15"
Y1="55"
X2="45"
Y2="55"
Stroke="Black"
StrokeThickness="2" />
<Line X1="20"
Y1="60"
X2="40"
Y2="60"
Stroke="Black"
StrokeThickness="2" />
</Canvas>
This is what it should look like after:
<Canvas>
<Path Data="M1,1 L41,1 M6.00001,6 L36,6 M11,11 L31,11"
Height="12"
Canvas.Left="9"
Stretch="Fill"
Stroke="Black"
StrokeThickness="2"
Canvas.Top="49"
UseLayoutRounding="False"
Width="42" />
</Canvas>

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;

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.

Rendering sharp lines in WPF

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):

Categories

Resources