how do you do freehand drawing on a panel

  • Thread starter Thread starter dongarbage
  • Start date Start date
D

dongarbage

Hi there,

I'm very much a C# novice.

How do you do freehand drawing on a panel with a mouse in c#?


Thanks,
Don
 
Well, it depends on what you need, but there are some key ideas. First
you need to know what to do someone drags something over your panel so
you need to buffer what ever you've drawn so you can redraw it when it
becomes visible.

Here's a tutorial on double buffering.

http://www.codeproject.com/csharp/DoubleBuffering.asp

You'll need to know how to set a single pixel or range of pixels,
there's a little info on this:

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1138408&SiteID=1

but it can be summed up as

//_ourbitmap is a reference to our buffer (System.Drawing.Bitmap)
_ourbitmap.SetPixel(e.X,e.Y,System.Drawing.Color.Azure);
//Draw using the stuff we learnt in double buffering.

Here's something that actually works. Create a form, add a panel and a
button.

Add this to the form's declarations. I'm using an existing bitmap for
simplicity to set up the bitmap
private System.Drawing.Bitmap _b = new Bitmap("C:\\Somebitmap.bmp");


In the buttons click event add

//ensure bitmap fits panel and assign.
_b = new System.Drawing.Bitmap(_b,panel1.Size);
panel1.BackgroundImage = _b;

In the MouseMove event of the panel add the following.

//if left button down, draw a pixel and invalidate it so it gets
redrawn.
if(System.Windows.Forms.MouseButtons.Left == e.Button)
{
_b.SetPixel(e.X,e.Y,System.Drawing.Color.Wheat);
panel1.Invalidate(new System.Drawing.Rectangle(e.X,e.Y,1,1));
}


It isn't perfect but it might get you started in the right direction.
 
Hi there,

I'm very much a C# novice.

How do you do freehand drawing on a panel with a mouse in c#?


Thanks,
Don

The best way, IMO, is to create a new class that inherits from Panel and
override the OnPaint, OnMousexxx, etc methods inside this class....but just
my opinion :)

HTH,
Mythran
 
Mythran,

This sounds the simplest. How do you draw on the panel when you're in
the OnMouseDown() method?

Thanks,
Don
 
Mythran,

This sounds the simplest. How do you draw on the panel when you're in
the OnMouseDown() method?

Thanks,
Don





override the OnPaint, OnMousexxx, etc methods inside this class....but
just
my opinion :)

HTH,
Mythran
[/QUOTE]

To draw, I would recommend drawing on an off-screen buffer (Bitmap) and then
in OnPaint, draw this buffer onto the panel. So, when a user fires
OnMouseDown, you would find the location of the mouse x and y relative to
the panel's dimensions and then color the pixel at the location x and y on
the offscreen image. Once done, you can fire off OnPaint by invalidating
the panel (Me.Invalidate).

To learn how to draw, I would recommend that you familiarizing yourself with
the System.Drawing namespace, and the System.Drawing.Graphics class. Look
those up on MSDN (http://msdn.microsoft.com/library).

HTH,
Mythran
 
Mythran,

I have tried to use the Graphics object and am having a problem. It
seems that only a small portion (sized at 100X200) of my panel can be
drawn on. My panel is sized at 500X500 but for some reason only the
upper left hand corner (100X200) receives scribbles from my mouse.
Weird thing is that the mousedown and mousemove events are triggered
throughout the panel. Here's the pertinent code inside my overridden
panel class:

private Point last_point = Point.Empty;
private Graphics g;
private Pen p = new Pen(Color.FromName("yellow"));
...
...
protected override void OnMouseDown(MouseEventArgs e)
{
mouse_down = true;
}
protected override void OnMouseUp(MouseEventArgs e)
{
mouse_down = false;
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (last_point.Equals(Point.Empty)) last_point = new
Point(e.X, e.Y);
if (mouse_down)
{
Point pMousePos = new Point(e.X, e.Y);
g.DrawLine(p, pMousePos, last_point);

}
last_point = new Point(e.X, e.Y);
}

Thanks,
Don
 
where are you setting g? Is it possible you're getting an invalidated
region as opposed to the full area? Post that bit of the code will help
:)
 
Hi there,

See code below:

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace MyProject
{
public class MyPanel : Panel
{
private Pen p;
public string pen_color = "yellow";
private bool mouse_down = false;
private Point last_point = Point.Empty;
private Graphics g;

public MyPanel()
{
g = this.CreateGraphics();
p = new Pen(Color.FromName(pen_color));
}
protected override void OnMouseDown(MouseEventArgs e)
{
mouse_down = true;
}
protected override void OnMouseUp(MouseEventArgs e)
{
mouse_down = false;
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (last_point.Equals(Point.Empty)) last_point = new
Point(e.X, e.Y);
if (mouse_down)
{
Point pMousePos = new Point(e.X, e.Y);
g.DrawLine(p, pMousePos, last_point);
}
last_point = new Point(e.X, e.Y);
}
}
}

Thanks for any help,
Don
 
I made this change:

protected override void OnMouseMove(MouseEventArgs e)
{
if(null == g)
{
g = this.CreateGraphics();
}

and it works correctly. I put it there to ensure the control was fully
initialised and set up. If you check this.width and this.height both in
the constructor and the mousedown event you'll see the control changes
size. That might be worth keeping in mind if you want to resize the
control while running.
 
OK, now I get it!! This is my eureka moment for this problem.
The panel is instantiated in my form designer.cs, then, parameters like
size are assigned values from the form designer.cs. The problem I was
having was that I was instantiating the Graphics object (g) in the
panel's constructor, before any of the panel's parameters were being
set thereby giving panel default values to the Graphics object.
Bingo!!!

Did I mention that I'm a novice with c#? ;)

Thanks so much for the help,
Don
 
Back
Top