this should be an easy answer for some of you maybe.
I wan to draw a line that is always 50% of my window width, how do i do that?
So if the user resizes the window, the line should be able to automatically adjust itself and grow/shrink to always keep 50% of my window width.
How to do that? Currently, i only have a very static line....such as....
<Polyline Points="0,0 1,0" HorizontalAlignment="Right" Width="500" Stretch="Fill" Stroke="Blue" StrokeThickness="10" />
where my window width is set to 1000.
You can create the same effect with a Path control. The Data property value uses a pair of Move elements to define the nominal size of the drawing surface.
<Path Stroke="Black" StrokeThickness="5" Data="M 100,0 M 0,0 L 50,0" Stretch="Uniform" />
Related
I have a Path based on a group of rectangle/ellipse Geometry. When I put an auto-sized Border around it, the border shrinks to fit the RectangleGeometry but does something weird with the EllipseGeometry, as shown below. Anyone know how to fix it so the Border (shown in blue) fits snugly around the whole thing?
Ultimately, I want a Border or a Panel that fits an arbitrary, runtime-generated Path (including the stroke thickness), and I need the geometry size maintained.
Sample code:
<Border BorderBrush="Blue" BorderThickness="2"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Path Stroke="Orange" StrokeThickness="5" Fill="Red">
<Path.Data>
<GeometryGroup>
<EllipseGeometry Center="-10,-10" RadiusX="12" RadiusY="12" />
<EllipseGeometry Center="70,0" RadiusX="70" RadiusY="10">
<EllipseGeometry.Transform>
<RotateTransform Angle="-25" CenterX="50" CenterY="0" />
</EllipseGeometry.Transform>
</EllipseGeometry>
<RectangleGeometry Rect="0,0,100,100" />
</GeometryGroup>
</Path.Data>
</Path>
</Border>
You may set the Path's Stretch property and bind its Width to the Width of the Bounds of the Geometry:
<Path ... Stretch="Uniform"
Width="{Binding Data.Bounds.Width, RelativeSource={RelativeSource Self}}">
...
</Path>
As the Geometries's Bounds do not contain the rendered Path's StrokeThickness, you may alternatively put the Border into a Canvas (which does not resize its child elements at all), and don't set the Path's Width. This may may however lead to problems when you want to center the Canvas in an outer Grid. It's actual size appears to be zero.
<Canvas>
<Border BorderBrush="Blue" BorderThickness="2">
<Path ... Stretch="Uniform">
...
</Path>
</Border>
</Canvas>
I have created a series of shapes in Illustrator, and exported them to an .ai file. When I import this file in Blend for Visual Studio, I get something that looks like this:
<Canvas x:Name="ManyPaths" Grid.Row="0">
<Path Data="F1M0,53.135L0.004,102.44 22.03,151.59 55.042,0z" Fill="#FF8B1A34" Height="151.59" Canvas.Left="0.017" Stretch="None" Canvas.Top="182.406" Width="55.042"/>
<Path Data="F1M0.003,34.152L22.027,49.15 0,0z" Fill="#FF991937" Height="49.15" Canvas.Left="0.02" Stretch="None" Canvas.Top="284.846" Width="22.027"/>
</Canvas>
There are numerous Paths, I won't list them all here for brevity. When put together, they make a fixed size rectangle. I would like to use this rectangle at the top of my app as the header image. I can resize the Canvas element in Blend, but I cannot get the collective Paths to fit the Canvas, and be resized along with it. Since I'm designing for various size screens, I would like the header image to scale. I have tried nesting it in a Grid, but that doesn't work.
Looks like the traditional way to do Paths in C# is
<Path Grid.Row="1" Stroke="Black" StrokeThickness="2" Fill="Green">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="100,100">
<QuadraticBezierSegment Point1="165,25" Point2="225,100" />
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
I'm not sure if there is a means to convert the first format to the second, but I would like to reuse my .ai files if possible, instead of recreating them from scratch.
There is no need to convert to the second format. Using the Data attribute is more concise and often clearer.
You can wrap your Canvas in a ViewBox to let it scale to its container. The Stretch attribute can control if it stretches uniformly or distorts (you probably want uniform)
<Viewbox Stretch="Uniform" Grid.Row="0">
<Grid x:Name="ManyPaths" >
<Path Data="F1M0,53.135L0.004,102.44 22.03,151.59 55.042,0z" Fill="#FF8B1A34" Height="151.59" Canvas.Left="0.017" Stretch="None" Canvas.Top="182.406" Width="55.042"/>
<Path Data="F1M0.003,34.152L22.027,49.15 0,0z" Fill="#FF991937" Height="49.15" Canvas.Left="0.02" Stretch="None" Canvas.Top="284.846" Width="22.027"/>
</Grid>
</Viewbox>
The figure below shows me changing two values for height. When I decrease the height instead of the figure decreasing from top to bottom the opposite happens.
<Rectangle Fill="#DBDBDB" HorizontalAlignment="Left" Height="100" Margin="547,607,0,0" Stroke="Silver" StrokeThickness="2" VerticalAlignment="Top" Width="100" RenderTransformOrigin="0,0.97" />
I just need to know how to set X and Y
If your rectangle happens to be on a Canvas, you can make use of the Canvas.Right and Canvas.Bottom
<Canvas>
<Button Click="Button_Click">Shrink It a Bit</Button>
<Rectangle x:Name="_Rectangle" Canvas.Bottom="20" Canvas.Right="20"
Fill="Black" Height="50" Width="50" />
</Canvas>
So now if you shrink it:
_Rectangle.Height = _Rectangle.Height - 5;
_Rectangle.Width = _Rectangle.Width - 5;
you'll notice that it shrinks from the top and left. You can use the appropriate combinations of Top/Bottom, Right/Left to get the effect you desire.
How can i resize Polygon which is placed in Canvas so it fills that canvas?
I don't want to change values of polygon points, I just want it to be displayed inside of canvas in case polygon coordinates are too large, too small or out of screen.
Came across this problem recently and worked out a solid solution:
<Canvas x:Name="CanvasName">
<Polygon Points="{Binding Path=PointCollectionName}" Stretch="Fill" Fill="Black"
Width={Binding ElementName=CanvasName, Path=ActualWidth}"
Height={Binding ElementName=CanvasName, Path=AcutalHeight}"/>
</Canvas>
Do you have the chance to replace the Canvas with a Grid? If so just set the Stretch attribute of the polygon, e.g. Uniform keeps the aspect ratio:
<Grid Width="297" Height="159">
<Polygon Points="10,110 110,110 110,10" Fill="Blue" Stretch="Uniform" />
</Grid>
With the following code I can demonstrate how a black panel with a opacity of 50% is on top of every rectangle:
<Grid>
<Rectangle Fill="Black" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Opacity="0.5" Canvas.ZIndex="1"/>
<Rectangle Fill="Red" Width="200" Height="200" Canvas.ZIndex="0"/>
<Grid>
<Rectangle Fill="Blue" Width="100" Height="100" Canvas.ZIndex="0"/>
<Rectangle Fill="Yellow" Width="50" Height="50" Canvas.ZIndex="1"/>
</Grid>
</Grid>
It looks like this:
I would like to have the yellow rectangle above the black panel, but that seems to be impossible.
I can achieve something close by setting the ZIndex of the Grid containing both the Blue and Yellow rectangles to "1". But this would also raise the blue rectangle above the black, and this is a problem.
<Grid>
<Rectangle Fill="Black" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Opacity="0.5" Canvas.ZIndex="1"/>
<Rectangle Fill="Red" Width="200" Height="200" Canvas.ZIndex="0"/>
<Grid Canvas.ZIndex="1">
<Rectangle Fill="Blue" Width="100" Height="100" Canvas.ZIndex="0"/>
<Rectangle Fill="Yellow" Width="50" Height="50" Canvas.ZIndex="1"/>
</Grid>
</Grid>
How do I get only the yellow rectangle above the black?
In my real application I have user controls instead of the rectangles. I like to make a particular control standing out by having everything else covered by the half-black shade.
Many Thanks,
I don't think you'll be able to achieve this with your current arrangement of controls.
There are two levels of controls here, the "Blue" and "Yellow" controls inside the inner grid and then the "Black" and "Red controls together with the inner grid.
The ZIndex works on controls at the same "level" - so you can ensure that the yellow control is on top of the blue, but then at the higher level these are grouped under the inner grid so are treated as a single unit.
The only way this would work is if all your controls were at the same level. If you included a second semi opaque rectangle in the inner grid you could get the yellow to be on top of that but that might end up making other controls too dark.
One approach might be to not use just a simple black rectangle.
Instead use a Path composed of two rectangles. The first rectangle will cover the whole area and the second would just cover the control to be available.
This creates a large rectangle with a hole in it where your target control can show through and accept input.
The down side is working out the rectangle geometry to add to create the hole but that's fairly straight forward.