I've been learning how to draw lines in winforms apps, and I'd like to be able to select something (rectangle, for example) that has already been drawn by left clicking it, and then be able to move it around to another location by dragging it with the mouse.
How can this be done? I don't see any methods for this so I think I will need to figure out if there is anything where I left-click on the form, and if there is, then somehow figure out the dimensions of it and redraw it appropriately. Is this correct? And how would I know where the reactangle starts, where it ends, how heigh it is, what color(s) it has, and what if it's overlapping another line, rectangle or another shape?
I've not been able to find much on the System.Drawing namespace for things like this, and what I have found so far is just basic "How to draw lines" type stuff.
Your drawing is a bitmap, not a vectorial image. Basically, it's just lots of pixels. Once your rectangle is drawn, it's just some pixels, but the rectangle itself (with coordinates and size) doesn't exist anymore.
What you can do is saving data for every shape (in a List for example). Then, when you click on your image to select something, you test every object in your list in reverse order until the mouse coordinates are within your shape. Then, if, for example, you want to delete the shape, you remove the shape from your list, then you clear your image and redraw every shape in your list.
Related
I am trying to do the following:
Open a new form and draw few lines and arcs (this is working well).
When an event occurs a new coordinate (x1,y1) is calculated, and a
small circle should be drawn at that coordinate.
When the next event occurs, a small circle should be drawn at
(x2,y2), and the first circle should disappear, while keeping the
lines and arcs that were drawn at step 1.
How do I delete the first circle while keeping all the rest?
Thank you
Once a circle has been drawn, there is no way to delete it. So, you need to clear the entire canvas with the background color and redraw everything.
So, you need to:
Come up with a bunch of "shape" classes for representing each line and each ark and each circle. They will probably all derive from some common base "Shape" class which offers methods that are common to all shapes, for example, a method to draw the shape on a canvas.
Instantiate objects from these classes to represent the shapes that are supposed drawn on the screen, and keep these objects in a list throughout the lifetime of your application.
When the event occurs, you make any changes to your shapes, (in your case, remove a circle and add another circle, or, more likely, change the coordinates of an existing circle without removing it and re-inserting it in the list,) and then you need to invalidate the canvas control that you presumably use for painting, (search for "Invalidate" for documentation,) so as to cause the canvas to repaint itself.
You override the paint method of the canvas control so as to do your painting: first you clear the control to its background color, and then you iterate through your list of shapes, calling each shape to draw itself on the canvas.
Of course this will cause flicker; if that's unacceptable, then you will need to read up on how to implement "double buffering" (look it up) to eliminate the flicker.
Another approach for flicker elimination is to only erase and repaint the area that has changed. In your case, that would be the smallest rectangle that contains both the circle in its old location, and the circle in its new location. So, instead of invalidating the entire canvas, you invalidate only that rectangle. The problem with this approach is that other shapes that cross the invalidated area might appear to be redrawn somewhat inaccurately. This may be unacceptable, or it may be acceptable, you will not know unless you try it.
You can't in the way you're thinking of, because the graphics works like MSPaint (a 2d array of pixels and when it's drawn, it's drawn) not Adobe Photoshop (layers or objects that can be moved independently)
The easiest thing to do is implement photoshop-like functionality yourself and keep eg a List of everything you want to draw, draw from the list (the list includes a circle) then later, remove that circle from the list, add another one and redraw the whole canvas from the list
I know it seems wasteful, and you probably could get into the mechanics of saving the pixels you drew over when you draw the first circle and restore them to erase the circle, but it's far more complex than just ditching it all and starting over every time
Is it possible to remove some lines in my graphic panel without erasing the rest?
PanelGraphics.Clear(Color.Black); erases all the graphics but I only want to remove one line, or a certain color.
Is this possible?
Is it possible to remove some lines in my graphic panel without erasing the rest?
Not really. The Graphics does not tell you anything about the actual context, it can be the screen, a printer, a bitmap, a metafile, the surface of a control or something similar. If you draw a Panel or a control you must always re-draw the whole content once it is invalidated. Otherwise, you will get a messy result. Just try to move your window partly out of the screen, the custom-drawn content will be "erased" unless you redraw it.
However, if you have a concrete image, such as a Bitmap, you can replace its colors; however, you must know the exact PixelFormat of the image. See my answer here if you are interested: https://stackoverflow.com/a/33562891/5114784
I want to write a GUI editor in C# for AutoIt, but I am not good enough with C#. I want to draw a square (focused) around an object when any object in the GUI is pressed. Like this:
Is there any library to make easier to write this kind of thing?
Square is drawn with one of DrawRectangle functions. Each of them requires a pen. Usually we use ordinary solid pen, but you need a pen with changed DashStyle property. For dotted lines change this property to DashStyle.Dot. You can also experiment with DashPattern property.
To draw little squares around the big square you need one of FillRectangle functions. Each of them requires a brush. You need a white brush, which is conveniently predefined for you to use. After filling a rectangle, you have to draw a rectangle over it with the same dimensions. These two functions together give an impression of empty and lined rectangle.
To make little squares a little rounded, like they are in the image, you have to change a pen parameter used when calling DrawRectangle. Experiment with LineJoin, and other properties of the Pen class.
This is very hard for a simple question that you posted. There are a lot of things that you need to take care of.
First I would suggest to make a class that will have a Rectangle property since you can't subclass Rectangle because it is a structure.
You will need to handle the drawing, that is the simplest task as mentioned in the other answers so I'm not going to be specific about that.
Since you have small squares that indicate that the rectangle can be resized, you will have to implement method that checks whether the mouse point is within the big rectangle or some of the small suqares. In this case you should change your cursor to indicate the possibility of resizing.
To handle moving (but not resizing) of the rectangle you will have either to make a new small square with the sign for moving in all directions or you will handle that using cursor when the mouse position is within the Big Rectangle.
The main problem is identifying what to change when resizing, you have two options:(1) to change Location and Size properties or to change X, Y, Width and (2)Height properties of the rectangle. For instance, when you are moving top-right corner you should change both Location and Size in first case or Y and Width is you are using second option.
When you move the mouse while it is clicked, you should watch out in which direction mouse moves. If you split the viewport in quadrants where the center of your rectangle is the center of the Decartes coordinate system, by identifying in which quadrant is the mouse you will know which corner (or edge) of the quadrant you need to move.
Each mouse move will have to call Invalidate() because you can't use Xor like in C++. Therefore, when your Rectangle is displayed, you should be in a special mode where everything that not moves (not changes, everything except Rectangle and selected control) should be drawn to the Bitmap that is used between two redraws and you should only draw what is moving.
As you can see, there is a lot of things that should be taken care of. You should start with this only after you are sure that you have already implemented other parts of your program.
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.
The scenario is that i want the user to create a shape in a small panel that opens (the added shape can later be placed on the canvas), but for a better reference, i want the user to be able to move the semi-transparent panel somewhere on the canvas and then draw with the accurate reference.
Please tell me:
Which panel type to use
How to make it moving by clicking the mouse on the move button (not the whole panel as dragging will be used for drawing lines) and move it around.
How to make it semi transparent.
How to make it appear and disappear (this should be pretty simple)
How to somehow limit its movement inside the canvas so it cannot move on the ribbon
And I really really hope there will be something built-in in WPF that i'll be able to use, and i will not have to do it the hard way i.e. create a rectangle, and do customized hit testing on it to allow the user to draw on top of that rectangle, make that rectangle transparent, and add graphics items for the buttons and controls on that rectangle "panel".
I am asking this because i have never seen such feature in any Windows application and i have no idea what to use for this purpose and how to implement it. The closest thing to what i want is in Adobe Acrobat Pro, which is the small preview of the page that appears when i double click with the middle mouse button. It doesn't move, nor it is transparent or can be drawn upon, but scale and shape wise i want something similar.
You should be able to place a second Canvas inside of your main canvas, and place whatever UserControl you'd like with your "view" inside of it.
You'll have to handle the mouse click/drag for moving it around yourself, but otherwise, it should be very straightforward.