Click here to Skip to main content
15,741,892 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I'm playing around with the System.Drawing namespace and wanted to try making a basic paint program. I'm having trouble with drawing shapes, specifically, how do I show the shape the user is drawing without having to redraw the whole screen?

Currently, when the user draws on the screen, they don't see the shape they're drawing until they release the mouse button. This is annoying and makes it hard to get the shape just right.

I thought using GraphicsState and Graphics.Save()/.Restore() would fix my problem, but whenever I go to draw a new shape, it erases the screen. I want the user to be able to see the shape as they drag the mouse around the screen.


To store each shape, I'm using an abstract shape class (aShapeData) that all shapes inherit from, and a list of shapes (List<aShapeData>) for undo/redo functionality.

Abstract aShapeData class:
C#
public virtual void Start(Point point, Graphics graphics)
{
    startPt = point;
    gfxState = graphics.Save(); // Not working as expected
}

public virtual void Moved(Point point, Graphics graphics)
{
    graphics.Restore(gfxState); // Not bringing back the form as it
                                // looked when it was saved.
}

public virtual void Stop(Point point, Graphics graphics)
{
    stopPt = point;
    Draw(graphics);
}


LineShape class inherits from aShapeData:
C#
public override void Moved(Point point, Graphics graphics)
{
    base.Moved(point, graphics);

    graphics.DrawLine(new Pen(Color.Black), startPt, point);
}

public override void Draw(Graphics graphics)
{
    graphics.DrawLine(new Pen(Color.Black), startPt, stopPt);
}


The form's OnPaint event handler:
C#
/// <summary>
/// Event raised when the form becomes invalidated. Each aShapeData object
/// in the shapeList has its "Draw(Graphics gfx)" method called, which handles
/// drawing each shape on the given graphic.
/// </summary>
private void MainForm_Paint(object sender, PaintEventArgs e)
{
    foreach (aShapeData element in currentState.shapeList)
    {
        element.Draw(currentState.graphics);
    }
}
Posted

1 solution

See, the main objective of drawing an image dynamically is to draw the image on every mouse move. You need to set the initial position, and while the user is dragging, you need to keep on drawing and Updating the control.

Also another thing, you need to also redraw the previous shape just drawn before this with the background color.

So,
On MouseDown start drawing.
On MouseMove, you are drawing based on current position,
You draw the existing shape with the backcolor.

So it will seem to you that the existing shape is erased and new shape is created dynamically until mouseup.


:thumbsup:
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900