I need to create a repeat symbol in XAML / WPF (procedural code would be ok too, though I'd prefer XAML if possible), something like the following, but I just need the not finished circle with the arrow (the white drawing in the button):
http://www.vista-style-icons.com/libs/phone/repeat.htm
I know how to create a circle in XAML, but I don't know how to create a not finished circle and add an arrow to the open end?
Thank you for any help!
You can create an unfinished circle by using an ArcSegment as a path segment in a Path shape. You specify the start and end point of the arc and the radius of the entire circle. You can render it on top of a blue circle by putting them in a grid:
<Grid Width="160" Height="160">
<Ellipse Fill="Blue"/>
<Path StrokeThickness="5" Stroke="White">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="115,45">
<ArcSegment Point="115,115" Size="50,50" IsLargeArc="True"/>
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
<Polygon Points="115,115 105,105 125,105 125,125" Fill="White"/>
</Grid>
You can also use the shorter Path Markup Syntax to create a StreamGeometry rather than a PathGeometry:
<Grid Width="160" Height="160">
<Ellipse Fill="Blue"/>
<Path Data="M 115,45 A 50,50 0 1 0 115,115"
StrokeThickness="5" Stroke="White"/>
<Polygon Points="115,115 105,105 125,105 125,125" Fill="White"/>
</Grid>
You'll need to work on it to get exactly the look you want, but that should give you the basic technique for drawing an unfinished circle with an arrow.
Related
I'm drawing a simple Path shows a simple triangle pointing down. This is what it's supposed to draw (shown on top of other stuff)
It works great except for one thing: No matter what value I give to the StrokeThickness, the triangle what shows up on my screen is the above picture. It never gets any thicker or thinner.
Here is the XAML. In this I have set the StrokeThickness to the absurd value of "200" just to see if anything would change. It didn't
<Path Grid.Row="0"
HorizontalAlignment="Right" VerticalAlignment="Top"
Width="30" Height="30" Stretch="Uniform"
StrokeThickness="200"
Data="{StaticResource ReplicaSurfacePathGeometry}"
Fill="White"
/>
This is the Geometry resource being drawn
<PathGeometry x:Key="ReplicaSurfacePathGeometry" FillRule="NonZero">
<PathGeometry.Figures>
m 600 1034.3 -501.52 -868.68
h1003
z
m 0 -120 397.6 -688.69
h-795.2
z
</PathGeometry.Figures>
</PathGeometry>
When I debug and use the live visual tree and look at the actual live properties of the path, it shows the StrokeThickness is indeed "200". But the line stays skinny.
I know this is something dumb on my part. What am I missing here?
The white line is the difference of the areas of the two triangle segments in the PathGeometry. It has nothing to do with a potential Stroke of the Path.
In order to make the StrokeThickness effective, set the Stroke property in conjunction with a more simple Geometry:
<Path Data="M0,0 L2,0 1,1.73 Z"
Width="30" Height="30" Stretch="Uniform"
Stroke="White" StrokeThickness="2"/>
I try to get into creation of custom controls with for WPF. I found many good
tutorials and advises on the web so I started width a really simple example to get
my hands dirty and get some practice. I figured out that the issue stumbled across
is not really related to the subject of custom controls. So I extracted the xaml code to a simple wpf form.
<Window x:Class="WpfVerticalAigmentTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="200" Width="200">
<Grid>
<Grid Height="40" Background="LightCyan" VerticalAlignment="Center">
<Path Stroke="Red"
StrokeThickness="20" VerticalAlignment="Center" >
<Path.Data>
<LineGeometry StartPoint="0,0" EndPoint="100,0"></LineGeometry>
</Path.Data>
</Path>
</Grid>
</Grid>
My expectation was to get a line centered in the grid and claiming the half of the stroke thickness on each side from the center. But as the linked image shows differs from my expectation.
"Resulting visualization"
So it look like I missed a detail about the line shape or linegeomtry. How do I get the the line displayed as shown in the following image?
"Expected result"
You need to match the Width and Height of the LineGeometry to the Width and Height of the Path and set the VerticalAlignment property to Bottom:
<Grid Height="20" Width="200" Background="LightCyan" VerticalAlignment="Center">
<Path Stroke="Red" StrokeThickness="20" VerticalAlignment="Bottom">
<Path.Data>
<LineGeometry StartPoint="0,0" EndPoint="200,0"></LineGeometry>
</Path.Data>
</Path>
</Grid>
If your goal is your the expectaions, and not the way how u have reached this, I could prefer to you this:
<Grid>
<Grid Height="40" Background="LightCyan" VerticalAlignment="Center">
<Border BorderThickness="10" VerticalAlignment="Center" BorderBrush="Red" />
</Grid>
</Grid>
The problem here is that the starting point of the XY Coordinates of the Path starts on the top left, and the stroke expands in both directions but thereby only makes the Path bigger to the bottom (I can't really tell you why, but that's just what seems to happen).
You can see this pretty good in the Design View:
To work around this simply move your Y Coordinates down half of the stroke size.
<Grid Height="40"
VerticalAlignment="Center"
Background="LightCyan">
<Path VerticalAlignment="Center"
Stroke="Red"
StrokeThickness="20">
<Path.Data>
<LineGeometry StartPoint="0,10" EndPoint="100,10" />
</Path.Data>
</Path>
</Grid>
Or wrap it in another control (Canvas is the commonly used controls for Paths) with the desired height:
<Grid Height="40"
VerticalAlignment="Center"
Background="LightCyan">
<Canvas Height="20" VerticalAlignment="Center">
<Path Stroke="Red"
StrokeThickness="20">
<Path.Data>
<LineGeometry StartPoint="0,10" EndPoint="100,10" />
</Path.Data>
</Path>
</Canvas>
</Grid>
And you are good to go:
I need to draw an Ellipse (or anything else?) that looks like my example (roughly drawed in paint what i mean)
Any Suggestions how to develop this ?
I tried Clip, but i can only cut off top or bottom then ( or am i doing sth wrong ?)
<Canvas Width="16" Height="16">
<Ellipse Fill="Red" MinHeight="16" Name="ellipse1" Stroke="White" StrokeThickness="1" MinWidth="16" >
<Ellipse.Clip>
<RectangleGeometry Rect="0,0,16,10"/>
</Ellipse.Clip>
</Ellipse>
</Canvas>
The best would be if it's a circle an dynamiclly changes the Size to the content
Thanks Markus
Use a Path
<Canvas>
<Path Data="M 30, 0 A 10,10 90 0 1 30,20 H 10 A 10,10 90 0 1 10,0 Z"
Fill="Red" Stroke="Black"/>
</Canvas>
I'm loving that screen shot that you've provided! Clip should be able to provide the top and bottom clipping that I think you're after, see below.
<Canvas Width="16" Height="16" Margin="80,50,421,254">
<Ellipse Fill="Red" MinHeight="16" Name="ellipse1" Stroke="White" StrokeThickness="1" MinWidth="16" Height="100" Width="100" >
<Ellipse.Clip>
<RectangleGeometry Rect="0,25,100,50"/>
</Ellipse.Clip>
</Ellipse>
</Canvas>
The properties of the RectangleGeometry are (in order) Left offset, Top offset, width, height. so start the clip region where you want the top cut off and stop it where you want the bottom cut off.
I am trying to create a red circle with a black x through it using XAML.
My problem is that they aren't aligned correctly.
What is the right way to do this?
This is what I've got so far:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image>
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="Red">
<GeometryDrawing.Pen>
<Pen Brush="Transparent" Thickness="0"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<EllipseGeometry Center="8,8" RadiusX="8" RadiusY="8"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing>
<GeometryDrawing.Pen>
<Pen Brush="Black" Thickness="2.5"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<PathGeometry>
<PathFigure StartPoint="4,4">
<LineSegment Point="12,12"/>
</PathFigure>
<PathFigure StartPoint="4,12">
<LineSegment Point="12,4"/>
</PathFigure>
</PathGeometry>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</Grid>
Simply putting an ellipse in the same grid with a black X the X isn't quite centered on the ellipse because the coordinates of each line you draw are really coordinates within the space allotted for it.
I think they needed to be in some sort of geometry or drawing aggregate to give them the same coordinate system. The geometry group and path are aggregators but both require their contents to have the same fill and stroke and the stroke and fill is different for the red circle (no stroke) and the black X (no fill).
The only aggregator that gives common coordinate systems and allows different fills & strokes for its members that I could find was the DrawingGroup.
The string shortcuts that work for creating a Path via its Data property don't appear to work for creating a PathGeometry so all had to be filled in by hand.
OK, so three hundred ways to skin a cat. Without fully understanding your use case I just came up with the fastest way to draw what you requested.
<Grid HorizontalAlignment="Left"
Height="80"
Margin="80,80,0,0"
VerticalAlignment="Top"
Width="80">
<Ellipse Fill="Red"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
<Path Data="M40,53 L48,69 62,69 49,46 61,24 48,24 C48,24 40,39 40,39 40,39 32,24 32,24 L18,24 30,46 17,69 31,69 z"
Fill="Black"
Margin="15"
Stretch="Fill"
HorizontalAlignment="Center"
VerticalAlignment="Center"
/>
</Grid>
This is probably outside what exactly you're looking for, but hopefully it at least gives you another way to think about it.
I had the same issue when trying to center text within an ellipse. The problem with using something like a TextBlock is that the kerning and escapement of each character is slightly different and so while the TextBlock element itself might be technically centered within the ellipse, this does not mean that the character will be centered in the ellipse. The character always appears to be too low and to the right of center in most situations.
I have had some success by wrapping the TextBlock in a ViewBox. While I am not fully versed in the technical implementation of the ViewBox, the ViewBox appears to wrap the visual rendering of the content which allows me to center that rendering more easily than trying to center to layout elements together.
I also seem to have better luck using an outer element that is of odd width/height rather than even width and height.
<Grid Width="19"
Height="19">
<Ellipse Fill="#FFB1413F"
StrokeThickness="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
<Viewbox HorizontalAlignment="Center"
VerticalAlignment="Stretch">
<TextBlock Text="X"
Margin="1"
FontWeight="Bold"
Foreground="White"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Viewbox>
</Grid>
I have a path shape that I would like to combine lines that have different line thicknesses?
The StrokeThickness property is set on the Path object so I cannot change it for different lines. This same issue would arise if I wanted to change my line color.
The reason I want to do this is so that I can draw an arrowhead. Charles Petzold arrowheads http://www.charlespetzold.com/blog/2007/04/191200.html don't work for me. If my line is dashed the closed arrowhead draws weirdly.
I figured a way to do it was to combine at the end of my path/line a new short line geometry that was thicker than the my original path/line and had TriangleLineCap, voila, got myself an arrowhead. But I can't combine geometries that have different line thicknesses and dashed types, etc.
Any ideas?
Just use multiple Path objects in a panel like a Canvas or a Grid where they will draw on top of each other:
<Grid>
<Path Stroke="Blue" StrokeThickness="2">
<Path.Data>
<EllipseGeometry Center="20 20" RadiusX="10" RadiusY="10" />
</Path.Data>
</Path>
<Path Stroke="Green" StrokeThickness="1" StrokeDashArray="1 2">
<Path.Data>
<LineGeometry StartPoint="10 20" EndPoint="30 20"/>
</Path.Data>
</Path>
</Grid>