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.
Related
My coordinates are relative to the control size, in the 0 to 1 range. I currently draw on my control using manual scaling by RenderSize, which works fine, but is surely the wrong way.
How can I draw directly in 0-1 coordinates instead?
You may use Path controls and scale their Data by applying an appropriate transform to the Geometry.Transform property, like in the trivial example shown below. This way you would scale the drawn shapes, but not their stroke thicknesses.
<Grid>
<Canvas>
<Canvas.Resources>
<ScaleTransform x:Key="transform"
ScaleX="{Binding Value, ElementName=scaleSlider}"
ScaleY="{Binding Value, ElementName=scaleSlider}"/>
</Canvas.Resources>
<Path Stretch="None" Stroke="Blue" StrokeThickness="2">
<Path.Data>
<RectangleGeometry Rect="0.1,0.1,0.8,0.4"
Transform="{StaticResource transform}"/>
</Path.Data>
</Path>
<Path Stretch="None" Stroke="Red" StrokeThickness="2">
<Path.Data>
<EllipseGeometry Center="0.6,0.5" RadiusX="0.3" RadiusY="0.3"
Transform="{StaticResource transform}"/>
</Path.Data>
</Path>
</Canvas>
<Slider x:Name="scaleSlider" HorizontalAlignment="Center" VerticalAlignment="Bottom"
Width="100" Minimum="100" Maximum="500"/>
</Grid>
I have a resource defined like this:
<Canvas x:Key="export"
Width="48"
Height="48">
<Path Fill="{DynamicResource CurrentColor}"
Data="M23,12L19,8V11H10V13H19V16M1,18V6C1,4.89 1.9,4 3,4H15A2,2 0 0,1 17,6V9H15V6H3V18H15V15H17V18A2,2 0 0,1 15,20H3A2,2 0 0,1 1,18Z" />
</Canvas>
And I'm using it like this:
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Margin="10,5,10,10"
Width="Auto"
Height="Auto">
<Button.Template>
<ControlTemplate TargetType="Button">
<Rectangle Width="48"
Height="48"
Fill="{DynamicResource CurrentColor}">
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill"
Visual="{Binding}" />
</Rectangle.OpacityMask>
</Rectangle>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
As can be seen I'm trying to set the rectangle size to 48x48 but the Path Data coordinates in the resource were defined to draw it as 24x24. No matter what I try I cannot strech the resource to fill the button. How can it be done?
I'm open to change the button implementation if needed. All I need is to be able to show the icon in the button in a certain color.
Remove canvas and use Stretch="Uniform" on the Path. If you want to reduce height/width of the Path, add it into eg. Grid or just set Width and Height of the Path:
<Grid Width="48" Height="48">
<Path Fill="{DynamicResource CurrentColor}"
Stretch="Uniform"
Data="M23,12L19,8V11H10V13H19V16M1,18V6C1,4.89 1.9,4 3,4H15A2,2 0 0,1 17,6V9H15V6H3V18H15V15H17V18A2,2 0 0,1 15,20H3A2,2 0 0,1 1,18Z" />
</Grid>
Try using HorizontalAlignment="Stretch" and VerticalAlignment="Stretch"
But then again if Width and Height are set they take precedence over the Stretch setting. See Microsoft on HorizontalAlignment.
I want to create a custom usercontrol to represent a player in a 2D map.
I had an ellipse to represent the player but I want to have on the border of the ellipse an arrow to indicate where the player is looking.
This is what I tried :
<Ellipse Width="17" Height="17" Stroke="Black" Fill="White" HorizontalAlignment="Center" />
<Path Data="M5,0 0,5 5,10" Fill="White" Stroke="Black" VerticalAlignment="Center" >
<Path.LayoutTransform>
<RotateTransform Angle="10"/>
</Path.LayoutTransform>
</Path>
the result :
That looks like what I want (it's not properly aligned but that's not the point here).
The problems are :
I know the position of the ellipse's center without the arrow
When the arrow will be on the right the relative position of the ellipse's center will be different --> I could solve this problem using a square control
My Circle has a textblock on top (Horitonzal + vertical center) to
display its id
How to move the arrow depending on the position looked ? I thought the easier might be to calculate an angle and rotate the whole control.
My first idea was to draw using any vector drawing software (illustrator for instance) the path, and get the coordinates of the path, and paste them in WPF.
then just rotate the usercontrol.
But doing this will also rotate the text and I don't want the text to rotate.
I'm stuck on this one, I hope my problem is enough described to be understood.
EDIT My first try :
<ControlTemplate TargetType="ContentControl">
<Grid Width="34" Height="34">
<Path x:Name="contour_forme"
Stroke="{TemplateBinding BorderBrush}"
StrokeThickness="1"
Stretch="Uniform"
Width="28"
Height="22"
HorizontalAlignment="Left"
Fill="{TemplateBinding Background}"
Data="M28.857,53.500 C24.537,53.487 20.477,52.380 16.938,50.443 C16.938,50.443 16.938,50.500 16.938,50.500 C16.938,50.500 16.785,50.350 16.785,50.350 C12.845,48.157 9.579,44.924 7.317,41.032 C7.317,41.032 -6.176,27.755 -6.176,27.755 C-6.176,27.755 8.206,14.530 8.206,14.530 C10.380,11.316 13.289,8.649 16.681,6.736 C16.681,6.736 16.938,6.500 16.938,6.500 C16.938,6.500 16.938,6.581 16.938,6.581 C20.525,4.615 24.641,3.496 29.021,3.509 C42.835,3.551 53.996,14.775 53.951,28.580 C53.906,42.385 42.670,53.542 28.857,53.500 ZM29.004,8.507 C17.953,8.474 8.965,17.400 8.929,28.443 C8.893,39.487 17.822,48.467 28.873,48.500 C39.924,48.533 48.912,39.608 48.948,28.564 C48.985,17.520 40.056,8.540 29.004,8.507 Z"
>
<Path.LayoutTransform>
<RotateTransform Angle="0" />
</Path.LayoutTransform>
</Path>
<TextBlock Style="{DynamicResource StyleTextes}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center"
Text="5"
/>
</Grid>
</ControlTemplate>
With the result :
As you can see I didn't manage to center the text inside my 22px circle.
My arrow is about 6 px height so I've created a control of 22 (circle's size expected) + 2 * 6px depending on the arrow position.
But when I try to rotate my path doing :
<Path.LayoutTransform> <RotateTransform Angle="90" />
</Path.LayoutTransform>
I have the following result :
I'm not sure on how I can keep the circle of my path in the center of the control when I rotate the path.
Just apply the RotateTransform to the "image" but not to the text.
Also I would use a render transform instead of a layout transform.
<Canvas Canvas.Left="206.333" Canvas.Top="119" Height="80" Width="80">
<Path Data="M244,99.333333 L210.16667,109.50034 244.83334,125.50034" Fill="#FFF4F4F5" Stretch="Fill" Stroke="Black" RenderTransformOrigin="0.5,0.5" Height="60" Canvas.Left="3" Canvas.Top="5" Width="60">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="70"/>
<TranslateTransform/>
</TransformGroup>
</Path.RenderTransform>
</Path>
<TextBlock TextWrapping="Wrap" Text="TextBlock" Height="20" Width="80" Canvas.Top="30" TextAlignment="Center"/>
</Canvas>
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 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.