viperchaos
viperchaos

Reputation: 395

How to move a circle drawn by GDI in .NET Framework with the mouse?

I drew some circles on the Form1 using GDI+, and the center of the circle is a small red rectangle of Custom Control which is derived from User Control, the BackgroundImage property ofForm1's a bitmap which is also drawn by GDI+ with several colors.

What I want is that when I move the red rectangle(the center of circle) with a mouse, the circle will also move following the red rectangle. Using the MouseDown, MouseMove event I could move the red rectangle smoothly with the mouse.

My problem is how to move the circle corresponding to the red rectangle(the center of circle). I enabled the double buffering to solve the flicker problem. CircleCenter is an object of Custom Control class(e.g. the red rectangle). GObject is a Grahpics object. Here is some key codes:

   public Form1()
   {
        InitializeComponent();
        this.SetStyle(ControlStyles.DoubleBuffer |    //enables double-buffering
                      ControlStyles.UserPaint |
                      ControlStyles.AllPaintingInWmPaint,
                      true);
    }

   Point CCenterPoint = new Point();
   private int Diameter = 250;
   private void CircleCenterMouseDown(object sender, MouseEventArgs e)
   {
        CCenterPoint = new Point(-e.X, -e.Y);
   }

    private void CircleCenterMouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
                Point MousePos = CircleCenter.MousePosition;
                MousePos.Offset(CCenterPoint.X, CCenterPoint.Y);
                CircleCenter.Location = CircleCenter.Parent.PointToClient(MousePos);
                CircleCenter.BringToFront();
                CirclePen.Color = Color.Black;
                GObject.DrawEllipse(CirclePen, CircleCenter.Left- Diameter/2, CircleCenter.Top - Diameter/2, Diameter, Diameter);
                 this.Invalidate();
        }
    }

How to remove the black circle drawn by GDI+ produced in the MouseMove proceed? I googled several websites and didn't get a satisfied answer. Hope you could give me some hints,Thx!

Upvotes: 0

Views: 2148

Answers (2)

Pavel Donchev
Pavel Donchev

Reputation: 1889

You will need to always reset the entire GObject (erase the images you drawn on it) and then redraw them all again.

This can be done by simply drawing a rectangle with the color of the object from which you obtained the Graphics object (although you didn't mentioned it, I think GObject is a Graphics object, obtained of some win control?).

So something like:

Control control = CircleCenter.Parent; // Parent control where you get Graphics object from.
System.Drawing.SolidBrush sBrush = new System.Drawing.SolidBrush(control.BackColor); // Brush to be used with the same color like the one of the parent control.
GObject.FilledRectangle(sBrush, new Rectangle(0, 0, control.Width, control.Height); // Erase background.
GObject.DrawEllipse(CirclePen, CircleCenter.Left- Diameter/2, CircleCenter.Top - Diameter/2, Diameter, Diameter); // Do your stuff.

should hide the old drawings and re-draw the circle on the new location.

Upvotes: 0

user915331
user915331

Reputation:

Well, As I understand from your question, You just need to draw a circle around the red rectangle, This is quite easy.

In the Paint event of the Form, Add the following (assuming that your red rectangle control has the name "CircleCenter" and your Form was named "Form1"):

private void Form1_Paint(object sender, PaintEventArgs e)
{
    // get the Graphics object of the form.
    Graphics g = e.Graphics;
    // create a think red pen for the circle drawing
    Pen redPen = new Pen(Brushes.Red, 4.0f);
    // drawing the circle
    PointF ctrlCenter = GetCenterOfControl(CircleCenter);
    g.DrawEllipse(redPen,
            ctrlCenter.X - (Diameter / 2),
            ctrlCenter.Y - (Diameter / 2),
            Diameter, Diameter);
}

//The following little method to calculate the center point
PointF GetCenterOfControl(Control ctrl)
{
    return new PointF(ctrl.Left + (ctrl.Width / 2),
            ctrl.Top + (ctrl.Height / 2));
}

Any way, I know it looks long for such a simple task like Circle drawing! here is the ugly one line version of the above code:

e.Graphics.DrawEllipse(new Pen(Brushes.Red, 4.0f), (centerCircle.Left + (centerCircle.Width / 2)) - (Diameter / 2), (centerCircle.Top + (centerCircle.Height / 2)) - (Diameter / 2), Diameter, Diameter);

Upvotes: 2

Related Questions