I'm trying to draw a Rectangle on a Canvas as follows:
System.Windows.Shapes.Rectangle rect;
rect = new System.Windows.Shapes.Rectangle();
rect.Stroke = new SolidColorBrush(Colors.Black);
rect.Fill = new SolidColorBrush(Colors.Black);
rect.Width=200;
rect.Height=200;
Canvas.SetLeft(rect,0);
Canvas.SetTop(rect,0);
front_canvas.Children.Add(rect);
Why would this code not draw a rectangle?
The canvas is defined in the associated XAML as follows:
<Canvas Height="200" Width="200" Name="front_canvas" Grid.Row="1" Grid.Column="0">
</Canvas>
The canvas shows up fine. I can tell because of the gap it leaves in the layout grid.
This should draw your rectangle as a 200x200 black square, provided front_canvas is displayed correctly.
Why would this code not draw a rectangle?
The main reasons this would not draw are:
front_canvas is not visible
front_canvas is not in the visual tree and being displayed correctly
Some other FrameworkElement is obscuring front_canvas, at least the upper left corner.
There is another object in the canvas at a higher z order.
Note that you'd typically also want to set StrokeThickness if you want to see the Stroke you specify.
To View Rectangle you must specify the StrokeThickness and set any Integer value greater than zero:
rect.StrokeThickness=2;
// ...
front_canvas.Children.Add(rect);
Size size = new Size(front_canvas.Width, front_canvas.Height);
front_canvas.Measure(size);
front_canvas.Arrange(new Rect(size));
Related
I'm trying to put a rectangle in a grid in a window that will change size regularly. I'm not working with absolute values, but with ratios.
So, there are three states the rectangle could have relative to the window/grid:
The default aspect ratio for the window is 16:9. If the window has that size, the rectangle should fit into the window perfectly, filling the window;
If the window's width is bigger than that, the rectangle should stretch with it. (So if the window's aspect ratio > 16/9, the rectangle stretches its width, thus still filling the entire window);
If the window's height is bigger than the 16:9 ratio, the rectangle inside should (1) not stretch vertically, and (2) align to the bottom of the grid.
This image explains it a lot clearer
I'm looking for a solution that doesn't involve changing code other than XAML, (so nothing in the .cs file), unless there is no other way. I did try finding a solution with C# code though:
RectName_OnSizeChanged(object sender, SizeChangedEventArgs) {
RectName.MaxHeight = 9/16 * RectName.Width;
}
but it doesn't seem to be working. (So why that is, is my bonus question)
How about this:
<Grid Background="CornflowerBlue" SizeChanged="ParentSizeChanged">
<Rectangle x:Name="theRect" Fill="Blue" HorizontalAlignment="Left" VerticalAlignment="Bottom" />
</Grid>
And this:
private void ParentSizeChanged(object sender, SizeChangedEventArgs e)
{
var parent = sender as FrameworkElement;
if (parent == null)
return;
theRect.Width = parent.ActualWidth;
theRect.Height = Math.Min(parent.ActualHeight, parent.ActualWidth * 6 / 9);
}
I am using "DrawArrowButton" method in my code and I can set the required size of the rectangle enclosing the Arrow but I cannot size the Arrow itself. My requirement is to increase the arrow height or width touch the rectangle side to side.
I am using the below code but I do not know how to resize the arrow.
Graphics g;
Rectangle rectLeftDown = new Rectangle(this.SplitterRectangle.Location, new Size(width, height));
ScrollBarArrowButtonState button1State = ScrollBarArrowButtonState.LeftNormal;
ScrollBarRenderer.DrawArrowButton(g, rectLeftDown, button1State);
Use the Graphics.ScaleTransform Method before drawing.
g.ScaleTransform(2, 2);
Now you can draw in double size (as an example).
I want to draw a rectangle on a canvas in WPF. For drawing a line I can do this:
line.X1 = ls.P0.X;
line.Y1 = ls.P0.Y;
line.X2 = ls.P1.X;
line.Y2 = ls.P1.Y;
MyCanvas.Children.Add(line);
...in other words the location is a property of the line itself. I want to draw a rectangle the same way, i.e., assign its coordinates and add it to my canvas. But the examples I've seen online so far seem to look like this:
rect = new Rectangle
{
Stroke = Brushes.LightBlue,
StrokeThickness = 2
};
Canvas.SetLeft(rect,startPoint.X);
Canvas.SetTop(rect,startPoint.X);
canvas.Children.Add(rect);
...in other words it doesn't look like the rectangle has an inherent location, but instead its location is set by calling a method of Canvas. Is this true - Lines have inherent coordinates but Rectangles do not? Is there any way to have a rectangle in WPF with an inherent location, like a line, or do I have to roll my own (using lines)?
You could use a Path control with a RectangleGeometry like this:
var rect = new Path
{
Data = new RectangleGeometry(new Rect(x, y, width, height)),
Stroke = Brushes.LightBlue,
StrokeThickness = 2
};
canvas.Children.Add(rect);
...in other words it doesn't look like the rectangle has an inherent location, but instead its location is set by calling a method of Canvas. Is this true - Lines have inherent coordinates but Rectangles do not?
Locations in WPF are relative, which begs the question: coordinates relative to what?
Line, Rectangle, and Path all inherit from Shape, and in the case of any Shape object, the coordinates of the defining geometry are relative to the top-left corner of the Shape itself. Thus, when you create a Line object from (100, 300) to (300, 100), the resulting element is 300x300 points in size, even though the visible line has bounds of 200x200:
In this case, it is unnecessary to place the Line within a Canvas, as you are not using the coordinate system of the Canvas.
Some shapes like Line and Path allow you to place geometry at any "internal" coordinates you like. Others, like Rectangle and Ellipse, always position their defining geometry at (0, 0) internally, forcing you to use other layout properties to position the shapes within the greater scene (e.g., Canvas.Top/Left, Margin, etc.).
In your example, if you were to define a Rectangle of 200x200 points, and use the Canvas attached properties to position the rectangle at (100, 100), the resulting Rectangle element would measure 200x200, while the parent Canvas would measure itself to be at least 300x300, which is arguably more intuitive:
(shading added for clarity)
You are correct in that this is rather inconsistent. You may find it useful to always use layout properties (e.g., Canvas.Left/Top) to position shapes within a scene such that all elements are using the same coordinate system.
I have a canvas in my Window and occasionally I want to take snapshots of the content.
I have the following method to do so:
private PngBitmapEncoder captureVisual(Visual v)
{
RenderTargetBitmap bmp = new RenderTargetBitmap(546, 410, 120, 96, PixelFormats.Pbgra32);
bmp.Render(v);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Interlace = PngInterlaceOption.On;
encoder.Frames.Add(BitmapFrame.Create(bmp));
return encoder;
}
I call this method with the following method which is called by a press button action(the idea is to add the picture to another canvas which will display the "photo":
private void take_photo(Object sender, RoutedEventArgs e)
{
System.Windows.Controls.Image photoImg = new System.Windows.Controls.Image();
BitmapEncoder enc = captureVisual(videoCanvas);
photoImg.Source = enc.Frames[0];
photoCanvas.Children.Add(photoImg);
}
The problem:
When I take the photo the origin of the photo/bitmap is not the origin of the canvas but the origin of the window. So the Canvas appears in the bitmap translated towards bottom/right in the same position as it is in relation to the top-left corner of the window. I have no idea why this is happening.
As an example see the pic below: There is white space to the top left and the actual content is translated to the bottom right. The origin should be where the actual image is located. I will try to put around a border to make it easier to visualize the problem(sorry I don't know how to put a border around the image if anyone knows please tell me or edit it yourself. Thanks).
Thanks to the comment of dowhilefor I got the answer from this link:
The problem is WPF implicitly adds the margins of the Canvas in relation to the parent container. In my case the parent container was a Grid and I didn't define any margins, the canvas was filling a specific cell. Nevertheless this somehow gets incorporated in the bitmap.
The solution, wrap the Canvas around another Canvas. That's stupid but it works. IMHO this is a bug in WPF:
<Canvas
Name="outerCanvas"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Grid.Row="1" Grid.Column="1">
<Canvas
Name="videoCanvas"
Canvas.Left="0"
Canvas.Top="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
/>
</Canvas>
I am working on a CAD program in WPF and I'm looking for a way to count the number of controls displayed when a particular brush is rendered.
So say I have an Ellipse:
<Ellipse x:Name="Ellipse" Canvas.Top="25" Canvas.Left="50" Width="400" Height="250" Stroke="DarkBlue" StrokeThickness="5" />
And I fill it with a VisualBrush from code behind:
VisualBrush tileCounter = new VisualBrush();
Rectangle rect = new Rectangle() { Width = 10, Height = 10, Fill = Brushes.Blue, Stroke = Brushes.BlueViolet, StrokeThickness = 1 };
tileCounter.Visual = rect;
tileCounter.TileMode = TileMode.Tile;
tileCounter.Stretch = Stretch.None;
tileCounter.Viewport = new Rect(0, 0, 10, 10);
tileCounter.ViewportUnits = BrushMappingMode.Absolute;
Ellipse.Fill = tileCounter;
Is there any way to get the VisualBrush to report back how many instances of the rectangle shape it has rendered as the fill of the Ellipse? Or are there code changes I could make to reference each visual individually from the parent using the Fill or Background?
I am currently working on a tool to draw figures that have any number of sides that are LineSegment, ArcSegment, or QuadraticBezierSegment and the brush is a grid that the user defines with entered hight, width, and grid size. The grid is also able to be realigned by the user. This makes simple mathematical solutions extremely hard to pull off and so a WPF solution would be preferable.
My ultimate goal is to get total number of visuals it attempts to render and then how much of each visual is rendered across the entire fill.
I'm sorry to tell you but I think you have to go the mathematical route.
Though I'm not entirely, sure I'd assume wpf is drawing that rect once and then caching the result, otherwise that visualbrush would not be performant. So essentially it really is only a texture, nothing where you could be aware of how many tiles have been drawn entirely or partially.