Hi all..
I have a problem in Drawing Rubber band lines
Consider the following:(Windows Application: C#)
I have two datagridview components in the form, one is left and another is right side.
there is some amount of space between these datagridview components .
I will click on the DataGridView cell and will drag a line from the left to the
displayable column on the right DataGridView. Remember I cannot
have two clicks.The
line should be drawn to the mouse pointer as it moves around the screen (i.e. rubberband line).
The code is as follows:
private void Form1_Load(object sender, System.EventArgs e)
{
//Size size = this.Size;
Size size = SystemInformation.PrimaryMonitorMaximizedWindowSize;
bitmap = new Bitmap(size.Width, size.Height);
gBm = Graphics.FromImage(bitmap);
Color bckColor = this.BackColor;
gBm.Clear(bckColor);
}
private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
Point p = new Point(e.X, e.Y);
x = p.X;
y = p.Y;
if (drag)
{
Graphics gx = CreateGraphics();
gx.DrawImage(bitmap, 0, 0);
gx.Dispose();
Graphics g = CreateGraphics();
Pen pen = new Pen(Color.Blue);
g.DrawLine(pen, x0, y0, x, y);
xPrev = x;
yPrev = y;
g.Dispose();
pen.Dispose();
}
}
private void Form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
Pen pen = new Pen(Color.Blue);
gBm.DrawLine(pen, x0, y0, x, y);
drag = false;
pen.Dispose();
}
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics gx = CreateGraphics();
gx.DrawImage(bitmap, 0, 0);
gx.Dispose();
}
private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
Point p = new Point(dtgXml.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false).Left + 100, dtgXml.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false).Top + dtgXml.Top + 8);
x0 = dtgXml.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false).Left + 100;
y0 = dtgXml.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false).Top + dtgXml.Top + 8;
xPrev = dtgXml.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false).Left + 100;
yPrev = dtgXml.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false).Top + dtgXml.Top + 8;
drag = true;
}
The problem is: When I click and drag over the form, the line doesn't appear. The line appears only for the following situation:
Click the cell and another click on the any area of the form, then the line appears.
How can I solve this?
Loading
ChrisPosted Mar 25, 2008, 12:20 PM
There are several problems with your code:
Firstly, when you click and hold the mouse over the cell, windows will direct all subsequent mouse messages to this control, not the form handlers that you have defined. You can check this by setting a breakpoint on your mouseup handler. If im right, this breakpoint will never fire.
Second:
Your drawing code is completely wrong. The reasons why your project doesnt work are numerous.
Graphics gx = CreateGraphics();
gx.DrawImage(bitmap, 0, 0);
gx.Dispose();
Graphics g = CreateGraphics();
Why are you creating two graphics() instances?
It is generally bad practice to draw anywhere appart from in the OnPaint method. The onpaint method is fired when the a control receives a paint message from windows.
Use the paint event, as it provides you with a graphics context, so you need not create one.
i.e
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics gx = e.Graphics; //Use the context provided
//gx.Dispose(); Dont dispose of context. It will be disposed of for you.
}
Instead of subscribing to the form events, you can also override the base method that fires the event. I.e
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e); //Be sure to call base method, so that event is raised and window is drawn by system.
//Drawing code goes here
}
If you type override (followed by a space) in vs.net, you will be presented with a list of members that may be overridden (i.e methods that were originally declared as virtual).
private void Form1_Load(object sender, System.EventArgs e)
{
//Size size = this.Size;
Size size = SystemInformation.PrimaryMonitorMaximizedWindowSize;
bitmap = new Bitmap(size.Width, size.Height);
gBm = Graphics.FromImage(bitmap);
Color bckColor = this.BackColor;
gBm.Clear(bckColor);
}
You dont seem to have declared gBm anywhere, and even if you had it would be wrong!
There is no need to draw onto a bitmap, you can just draw directly to the control/window from the OnPaint method override (or event). If you wanted to double buffer the output, simply add the following line to your Form Load code:
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint,true);
That will setup the environment so that there is no flickering, and it will automatically refresh the screen when you change the size of the window.
Also, You are trying to paint on the forms graphic context. However your data control is on top of the form, so even if you were managing to draw, it would be drawn behind your control.
My advice to you is to start of with something more basic until you have a grasp of GDI+.
Try following some basic gdi+ tutorials on google.
Hope this helps.
Chris