Equivalent of canvas in Windows forms - c#

I am creating a simple app to display multiple images one below the other.
In WPF, I used Number of canvas equivalent to number of images and added those canvas to the main canvas.
And using Image control in each canvas, i uploaded the images with me and it is looking good.
Now, I Am trying to do the same in Windows forms.
I tried Panel (as the main canvas in WPF) and draw images over it by using Panel_Paint event. it is fine. But I need to add something(as I added multiple canvas in WPF), but did not get strike any thing.
I planned for few panels, but all them need Panel_Paint to draw images over it.That is some what difficult to maintain... any other ideas?

You can create your own custom control and override OnPaint method. There you will be able to draw whatever you like in Canvas like mode. Create element specify its coordinates, draw it with Graphics object. And for overlaying use linear drawing order, items drawn later will be top most.

If you want to create a Paint-like canvas, where you can draw simple graphics and images, you could use an instance of Graphics, like the following:
// myPictureBox is the control where your graphics will be drawn
Graphics myCanvas = myPictureBox.CreateGraphics();
If you want to display a group of images, like .jpg are displayed in the files explorer, you could use a ListView.

Related

Xamarin C# XAML Cross-Platform With Buttons Bound To Custom Graphic

Here's the basic idea of what I'm trying to do; have this (see image link) graphic with roots going into the ground and the roots split off into different directions. At the end of each root I'd like to place a round button with a number in it which will take them to a new page. (the image only shows a few buttons but later on, for updates i'll have more lessons, meaning more buttons, and so the page would scroll down revealing more buttons)
What I have tried; I tried drawing a dynamic root system graphic, which worked and resized properly based on the screen size. But Skiasharp doesn't really work with absolute layouts and adding buttons on top of the SKCanvas. From my understanding absolute layouts are the only way to but buttons in customs spots.
I'd like to have the Graphic dynamic and locked onto the buttons. I'v tried just placing the buttons over the top of a background image that already had the root graphic on it. But, they don't always align properly.
Is there a way to make this work, or another way to draw the graphic and have the buttons bound to the end of the roots? Or am I just stuck with not having them align with a static background image?
Concept image for app page is below:

How can I capture as bitmap only what a picturebox is displaying, without using "copy from screen"?

Specifically: I need to capture as a bitmap a specific region of what a picturebox is actually displaying. The coordinates of the region are specified by the bounds of a control that I have overlayed on top of the picturebox (but that belongs to the picturebox). The control is hidden when I make the "snapshot" of the region.
I tried using normal screen capture methods (CopyFromScreen), but you can't really control the timing there. So it was capturing "interstitial" states, like transitions between photos in my picturebox. Frequently it was only capturing purely black images (the background color of the picture box).
So I tried just converting the image (picturebox.image property) being displayed to a bitmap. The problem there is that the picture box is rarely showing exactly the image. It's displaying some PORTION of the image, scaled and clipped as appropriate to it's sizemode (which is zoom). So the I can't just take my control coordinates and clip them from the image as a whole.
So I tried to estimate what portion of the image was being displayed, and correcting my rectangle based on that. Turns out that I was basically re-creating the "zoom" code of the picturebox to do this (using aspect ratio of the picturebox, the aspect ratio of the image, guessing at what level of scaling is currently happening to the image if it's larger or smaller than the picturebox, etc). It was not pretty.
So: now I need a method of just capturing only the bitmap currently being displayed in the client area of the picturebox, including the photo and any black "letterboxing" currently being displayed around it. Anybody got one?
Remember that I can't rely on using CopyFromScreen. It's not reliable enough for my purposes. I think I need a method of getting picturebox to TELL me the bits it is displaying.
This will copy and save the currently shown content of the PictureBox including a BackgroundImage (if there is one and if it shines through) and also all Controls that belong to the PictureBox, like Labels etc.. Also included are elements drawn in the Paint event. Things drawn outside the Paint event are non-persistent and will not be included.
using (Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width,
pictureBox1.ClientSize.Height))
{
pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle);
bmp.Save(yourfilename, ImageFormat.Png);
}
Note: On my test Form the PicureBox is sitting inside an AutoScroll Panel pan_PBscroll. The PictureBox is displaying pixels 1:1 and is therefore, with a photograph loaded, much bigger than the Panel, the Form or even the Screen. So to clip to the actually visible parts I could not use the pictureBox1.ClientSize and pictureBox1.ClientRectangle but used the dimensions of that Panel. This may well apply to you, too.
I'm not sure about your timing issues. But since you mentioned CopyFromScreen here are a few differences:
CopyFromScreen makes a 1:1 copy of each screen pixel
This includes non-persistent drawings and excludes anything covered or hidden
Control.DrawToBitmap makes the Control draw itself onto a Bitmap, just as it draws itself during Paint
This excludes anything that doesn't belong to the Control but includes all members of its Controls collection
This also excludes non-persistent drawings but includes the full Size of the Control, whether it fits on the Form or Screen or not and whether it is hidden or covered or not.
For Controls with active Scrollbars only the visible parts are copied. To copy all you need to resize it temporarily. Then you can get a complete image of a listbox even if it has a thousand items..
Since you're using a PictureBox I would say to take a look PictureBox.Image where you can get the Bitmap object.
Hope it helps.

Create an effect of magnifying glass for a picturebox

I would like to know how to create an effect of a magnifying glass for a picturebox.
Not zooming the picturebox but magnifying a part of the the image in the PictureBox control (circle or rectangle) and setting the size of the glass and the magnification factor.
It may only work within the picturebox control.
Language: C#
Thanks in advance !
Basically, you'd need two pictureboxes. One for the whole image and another for the magnified section. Also, you have to place the magnified picturebox according to user's mouse position.
You'll find a good article about it at http://www.codeproject.com/Articles/21097/PictureBox-Zoom. Just change the source to show the second picturebox in appropriate place (under user's cursor position).
You need 2 picturebox objects, one for picture itself and second for magnified area.
Next load picture into memory, you haven't specified source of the picture but in any case I recommend using streams.
Then create bitmap image in memory.
Using Image method set property of a picturebox.
To create source image for magnifying picturebox you need to clone selected part (calculating dimensions of a new picture area). Whole thing is not as trivial as you may expect as clone method accepts Rectangle objects as an area selector and generally works on rectangles rather than circles to copy selection. I also recommend to Dispose() unused bitmap objects as soon as possible.
Hope this helps.

Group items on a Canvas

I am creating shapes on a wpf using a Canvas. I have created by C# code some Rectangles, each one of which is assigned with three circles and a TextBlock. I want now to make them move on the Canvas by a mouseEvent , in other words to drag them with the mouse and to move them on the Canvas. How is it possible to manipulate each Rectangle with the circles and the TextBlock as a compact group?
It is required, when the user clicks on the Rectangle to transfer it with its contents. However, the circles and the textBlock have their own coordinates, so if not grouped they stand still. How can I get over this?
Put the rectangle and everything else in a grid or another canvas, as described in this related question of yours: Drawing circles on a Rectangle
This is basically a user control composed of the rectangles, circles, and textbox, and you just allow that whole user control to be moved around, rather than the constituent parts.
If you don't want to add another layout panels try to apply the same transform to all elements you want to move, it's not so heavy solution.

Zooming and panning an image canvas

I have a silverlight Canvas which holds an image with drawings on it (polygons). I need to develop a control to zoom and pan this canvas within a work area (Border within a Grid cell, as of now) as shown below. What is the best way to do this. Is there any libraries I can make use of?
I need to be able to add drawings to the zoomed/panned canvas too.
Lots of code examples available on the internet. Check out ZoomControl and CodePlex.
You can try creating a UserControl that is basically an image inside a canvas, and expose two transform properties to control the zooming and panning. A ScaleTransform would handle zooming, and a TranslateTransform would handle panning. You can create a CompositeTransform from both of them and assign that as the RenderTransform of the canvas.
You can bind the zoom slider to the ScaleTransform, and handle mouse events to change the TranslateTransform. As long as you get the mouse coordinates relative to the canvas itself that should work (i.e. mouseEventArgs.GetPosition(canvas)).

Categories

Resources