drawing flickers - c#

have made something to draw on the screen(as overlay for everyting else) but when I move something over the drawing it starts flickering, I have already set DoubleBuffered on true
is their a way to fix this with a dll,function,rendering?
private void button2_Click(object sender, EventArgs e)
{
DoubleBuffered = true;
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Point midx = new Point(960, 960);
Point midy = new Point(540, 540);
Point LinksBoven = new Point(10, 10);
Point pt = Cursor.Position;
string letter = "drawing on";
float emSize = 12;
while (true)
{
using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
{
System.Drawing.Pen myPen;
myPen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(0, 200, 0));
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
if (cbCircel.Checked == true)
{
g.DrawEllipse(Pens.Black, midx.X - 10, midy.Y - 10, 20, 20);
}
if (cbKruis.Checked == true)
{
g.DrawLine(myPen, 940, 540, 980, 540);
g.DrawLine(myPen, 960, 560, 960, 520);
}
pt.X = 10;
pt.Y = 10;
g.DrawString(letter, new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular), new SolidBrush(Color.Green), pt);
}
}
}

Related

Zoom pictures in PictureBox

I have a picture and a line in a PictureBox control. I know how to zoom the picture itself using this code :
private void pictureBox1_Click(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (Globals.x == 1)
{
Globals.y = 1;
Globals.a = e.X;
Globals.b = e.Y;
}
}
}
private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
// Create a local version of the graphics object for the PictureBox.
Graphics g = e.Graphics;
if (Globals.y == 0)
{
e.Graphics.DrawImage(bitmap, 0, 0, 470, 353);
e.Graphics.DrawLine(System.Drawing.Pens.Red, 210, 66, 112, 122);
e.Graphics.DrawLine(System.Drawing.Pens.Red, 112, 122, 15, 205);
}
Bitmap bmpZoom = new Bitmap(bitmap.Width, bitmap.Height);
int new4W = bitmap.Width / 3;
int new4H = bitmap.Height / 3;
int new2W = bitmap.Width *2/ 3;
int new2H = bitmap.Height *2/ 3;
Rectangle srcRect = new Rectangle(Globals.a - new4W,Globals.b - new4H, new2W, new2H);
Rectangle dstRect = new Rectangle(60, 10, bmpZoom.Width, bmpZoom.Height);
}
My code can zoom the part of the picture that i have clicked on, but when I try to draw the line again, it's in the same location anymore (and that is normal).
I want a solution that can zoom both the picture and the line. If anyone could help me, I would be glad.

Why when i create the bitmap it's empty all white?

private Bitmap CropImage()
{
Bitmap pic = pictureBoxSnap.Image as Bitmap;
Bitmap cropped = new Bitmap(rect.Width, rect.Height);
using (Graphics g = Graphics.FromImage(cropped))
{
g.DrawImage(pic, new Rectangle(0, 0, rect.Width, rect.Height),
rect, GraphicsUnit.Pixel);
}
pic.Save(#"c:\temp\testingitimage.jpg");
cropped.Save(#"c:\temp\testingitimage1.bmp");
return cropped;
}
I added this two lines of Save to test what i get. The first one pic i see the correct image that is in the pictureBox.
But the second one cropped is all white and empty.
And i call this method from the pictureBox paint event:
private void pictureBoxSnap_Paint(object sender, PaintEventArgs e)
{
if (pictureBoxSnap.Image != null)
{
{
if (ClearGraphics == false)
{
if (cropRect == false)
{
if (rectangles[listBoxSnap.SelectedIndex] != Rectangle.Empty)
{
e.Graphics.DrawRectangle(Pens.Firebrick, rectangles[listBoxSnap.SelectedIndex]);
}
}
else
{
if (rect.Width > 10 && rect.Height > 10)
{
e.Graphics.DrawRectangle(Pens.Gray, rect);
pictureBoxSnap.Image = CropImage();
Image img = CropImage();
img.Save(#"c:\temp\testimageing.jpg");
}
}
}
}
}
}
I used a breakpoint on the: e.Graphics.DrawRectangle(Pens.Gray, rect); and rect is not empty ( rect is Rectangle i draw on the pictureBox then when i click on a button it's making validate for the pictureBox).
I also did a save here too and testimageing i see it black on the hard disk but when i edit it with Paint i see it's white empty.
For exmaple when i draw a rectangle on the pictureBox then i use a breakpoint in the CropImage method i see that the variable rect is for example: X = 136 Y = 149 Width = 131 Height = 106
Also in the paint event this rect variable have the same values.
And the pictureBox size is: 640x480
And the pictureBox property SizeMode is set to: zoom
Wo why i get empty white image ? And not the cropped rectangle with the part of the image inside ?
EDIT:
This is the code im using now:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using DannyGeneral;
using System.Diagnostics;
namespace MinimizeCapture
{
public partial class Form1 : Form
{
Boolean bHaveMouse;
Point ptOriginal = new Point();
Point ptLast = new Point();
bool cropRect;
Bitmap cloneBitmap;
Rectangle recttest;
private Rectangle Rect;
private Rectangle[] rectangles;
private Rectangle RectClone;
private bool btn = false;
private Point RectStartPoint = Point.Empty;
private Point RectEndPoint = Point.Empty;
private Brush selectionBrush = new SolidBrush(Color.Red);
private Pen pen;
private string selectedIndex;
private List<string> drawnItems = new List<string>();
private bool ClearGraphics;
public Form1()
{
InitializeComponent();
cropRect = false;
var windows = OpenWindowGetter.FindWindowsWithText();
ClearGraphics = false;
this.DoubleBuffered = true;
btn = false;
pen = new Pen(selectionBrush);
buttonSnap.Enabled = false;
backgroundWorker1.RunWorkerAsync();
}
private void buttonSnap_Click(object sender, EventArgs e)
{
ClearGraphics = true;
this.listBoxSnap.Items.Clear();
this.pictureBoxSnap.Image = null;
backgroundWorker1.RunWorkerAsync();
}
private void listBoxSnap_SelectedIndexChanged(object sender, EventArgs e)
{
WindowSnap snap = this.listBoxSnap.SelectedItem as WindowSnap;
selectedIndex = this.listBoxSnap.SelectedIndex.ToString();
this.pictureBoxSnap.Image = snap.Image;
for (int i = 0; i < rectangles.Length; i++)
{
if (rectangles[i] != RectClone)
{
ClearGraphics = false;
}
else
{
ClearGraphics = true;
}
}
}
private void checkBoxForceMDI_CheckedChanged(object sender, EventArgs e)
{
WindowSnap.ForceMDICapturing = (sender as CheckBox).Checked;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.Add("Minimized Windows"); }));
listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true,true).ToArray()); }));
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
rectangles = new Rectangle[listBoxSnap.Items.Count];
buttonSnap.Enabled = true;
}
private void pictureBoxSnap_Paint(object sender, PaintEventArgs e)
{
if (pictureBoxSnap.Image != null)
{
{
if (ClearGraphics == false)
{
if (rectangles[listBoxSnap.SelectedIndex] != Rectangle.Empty)
{
e.Graphics.DrawRectangle(Pens.Firebrick, rectangles[listBoxSnap.SelectedIndex]);
}
}
if (cropRect == true)
{
if (recttest.Width > 10 && recttest.Height > 10)
{
//e.Graphics.DrawRectangle(Pens.Gray, recttest);
e.Graphics.Clear(Color.White);
/*pictureBoxSnap.Image = CropImage();
Image img = CropImage();
img.Save(#"c:\temp\testimageing.jpg");*/
}
}
}
}
}
private void pictureBoxSnap_MouseMove(object sender, MouseEventArgs e)
{
if (btn == true)
{
ClearGraphics = false;
RectEndPoint = e.Location;
int currentindex = listBoxSnap.SelectedIndex;
rectangles[currentindex] = RectClone;
Rect = getRect(RectStartPoint, RectEndPoint);
RectClone = Rect;
pictureBoxSnap.Invalidate();
}
Point ptCurrent = new Point(e.X, e.Y);
// If we "have the mouse", then we draw our lines.
if (bHaveMouse)
{
// If we have drawn previously, draw again in
// that spot to remove the lines.
if (ptLast.X != -1)
{
MyDrawReversibleRectangle(ptOriginal, ptLast);
}
// Update last point.
ptLast = ptCurrent;
// Draw new lines.
MyDrawReversibleRectangle(ptOriginal, ptCurrent);
}
}
private void pictureBoxSnap_MouseDown(object sender, MouseEventArgs e)
{
RectStartPoint = e.Location;
btn = true;
Rect = Rectangle.Empty;
RectClone = Rectangle.Empty;
bHaveMouse = true;
// Store the "starting point" for this rubber-band rectangle.
ptOriginal.X = e.X;
ptOriginal.Y = e.Y;
// Special value lets us know that no previous
// rectangle needs to be erased.
ptLast.X = -1;
ptLast.Y = -1;
}
private void pictureBoxSnap_MouseUp(object sender, MouseEventArgs e)
{
recttest = rectangles[listBoxSnap.SelectedIndex];
ClearGraphics = false;
btn = false;
RectEndPoint = e.Location;
pictureBoxSnap.Invalidate();
int currentindex = listBoxSnap.SelectedIndex;
rectangles[currentindex] = RectClone;
// Set internal flag to know we no longer "have the mouse".
bHaveMouse = false;
// If we have drawn previously, draw again in that spot
// to remove the lines.
if (ptLast.X != -1)
{
Point ptCurrent = new Point(e.X, e.Y);
MyDrawReversibleRectangle(ptOriginal, ptLast);
}
// Set flags to know that there is no "previous" line to reverse.
ptLast.X = -1;
ptLast.Y = -1;
ptOriginal.X = -1;
ptOriginal.Y = -1;
pictureBoxSnap.Invalidate();
}
Rectangle getRect(Point p1, Point p2)
{
Point p = new Point(Math.Min(p1.X, p2.X), Math.Min(p1.Y, p2.Y));
Size s = new Size(Math.Abs(p1.X - p2.X), Math.Abs(p1.Y - p2.Y));
return new Rectangle(p, s);
}
private void ConfirmRectangle_Click(object sender, EventArgs e)
{
ConfirmRectangle.ForeColor = Color.Red;
ConfirmRectangle.Enabled = false;
StreamWriter w = new StreamWriter(#"c:\temp\Settings.txt", true);
w.WriteLine("Rectangle Location: " + RectClone.Location + " Rectangle Size: " + RectClone.Size + " Selected Index: " + selectedIndex);
textBoxIndex.Text = selectedIndex.ToString();
w.Close();
cropRect = false;
//pictureBoxSnap.Invalidate();
Image img = CropImage();
img.Save(#"c:\temp\testimageing.jpg");
pictureBoxSnap.Image = img;
}
// Convert and normalize the points and draw the reversible frame.
private void MyDrawReversibleRectangle(Point p1, Point p2)
{
Rectangle rc = new Rectangle();
// Convert the points to screen coordinates.
p1 = pictureBoxSnap.PointToScreen(p1);
p2 = pictureBoxSnap.PointToScreen(p2);
// Normalize the rectangle.
if (p1.X < p2.X)
{
rc.X = p1.X;
rc.Width = p2.X - p1.X;
}
else
{
rc.X = p2.X;
rc.Width = p1.X - p2.X;
}
if (p1.Y < p2.Y)
{
rc.Y = p1.Y;
rc.Height = p2.Y - p1.Y;
}
else
{
rc.Y = p2.Y;
rc.Height = p1.Y - p2.Y;
}
// Draw the reversible frame.
rect = new Rectangle(pictureBoxSnap.PointToClient(rc.Location), rc.Size);
ControlPaint.DrawReversibleFrame(rc, Color.Gray, FrameStyle.Dashed);
}
Rectangle rect = Rectangle.Empty;
private Bitmap CropImage()
{
//rect = recttest;
Bitmap pic = pictureBoxSnap.Image as Bitmap;
Bitmap cropped = new Bitmap(rect.Width, rect.Height);
using (Graphics g = Graphics.FromImage(cropped))
{
g.DrawImage(pic, new Rectangle(0, 0, rect.Width, rect.Height),
rect, GraphicsUnit.Pixel);
}
pic.Save(#"c:\temp\testingitimage.jpg");
cropped.Save(#"c:\temp\testingitimage1.bmp");
return cropped;
}
}
}
Moved the CropImage call method from the paint and added it to the button click here:
private void ConfirmRectangle_Click(object sender, EventArgs e)
{
ConfirmRectangle.ForeColor = Color.Red;
ConfirmRectangle.Enabled = false;
StreamWriter w = new StreamWriter(#"c:\temp\Settings.txt", true);
w.WriteLine("Rectangle Location: " + RectClone.Location + " Rectangle Size: " + RectClone.Size + " Selected Index: " + selectedIndex);
textBoxIndex.Text = selectedIndex.ToString();
w.Close();
cropRect = false;
//pictureBoxSnap.Invalidate();
Image img = CropImage();
img.Save(#"c:\temp\testimageing.jpg");
pictureBoxSnap.Image = img;
}
This lines:
Image img = CropImage();
img.Save(#"c:\temp\testimageing.jpg");
pictureBoxSnap.Image = img;
But what i get in the pictureBox is this:
Not sure why. The rectangle is in the position i drawed it's ok but instead showing the part of the original image cut in the rectangle it's doing like zoom in.
You are cropping multiple times.
pictureBoxSnap.Image = CropImage(); // First Time
Image img = CropImage(); // Second Time
img.Save(#"c:\temp\testimageing.jpg");
You just need to crop once. Here you are using same picturebox for source and for cropped image. first time when you crop then image. the cropped image will be set correctly to the picturebox. but, second time application will try to crop that image again.
You should do like this
Image img = CropImage();
img.Save(#"c:\temp\testimageing.jpg");
pictureBoxSnap.Image = img;
private Bitmap CropImage(){
Bitmap pic = pictureBoxSnap.Image as Bitmap;
Bitmap cropped = new Bitmap(rect.Width, rect.Height);
using (Graphics g = Graphics.FromImage(cropped)){
g.DrawImage(pic, new Rectangle(0, 0, rect.Width, rect.Height),
rect, GraphicsUnit.Pixel);
}
using (Graphics g = Graphics.FromImage(pic)){
g.DrawImage(cropped , 136, 149, rect.Width, rect.Height);
//Draw the rectangle
}
//pic.Save(#"c:\temp\testingitimage.jpg");
//cropped.Save(#"c:\temp\testingitimage1.bmp");
return pic;
}
valter

How do I keep animations from flickering in C# game programming?

Everytime I try to add a new line or move the paddle in this game the screen flickers.
How do I keep the screen from flickering when I move the paddle or add a line?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class GameTest : Form
{
int dx=3, dy=3, i =500, o = 100;
int rex = 400, rey = 450 ;
double c =0;
public GameTest()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Graphics g = this.CreateGraphics();
Invalidate();
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
Graphics g = this.CreateGraphics();
if (e.KeyCode == Keys.Left)
{
//Graphics g = this.CreateGraphics();
Invalidate();
Brush black = new SolidBrush(Color.White);
g.FillRectangle(black, rex, rey, 200, 20);
rex -= 40;
Brush red = new SolidBrush(Color.Green);
g.FillRectangle(red, rex, rey, 200, 20);
}
if (e.KeyCode == Keys.Right)
{
//Graphics g = this.CreateGraphics();
Brush white = new SolidBrush(Color.White);
g.FillRectangle(white, rex, rey, 200, 20);
rex += 40;
Brush red = new SolidBrush(Color.Green);
g.FillRectangle(red, rex, rey, 200, 20);
}
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
DoubleBuffered = false;
Graphics g = this.CreateGraphics();
// Bitmap bmp1 = new Bitmap("G:\c#\Bouncing ball\Pic.jpg");
//TextureBrush tb2 = new TextureBrush(bmp1);
Brush green = new SolidBrush(Color.Green);
g.FillRectangle(green, rex, rey, 200, 20);
Graphics b= this.CreateGraphics();
Brush red = new SolidBrush(Color.Red);
b.FillEllipse(red, i, o, 20, 20);
Pen p = new Pen(Color.Black, 10);
//
g.DrawLine(p, 1000, 480,0,480);
g.DrawLine(p, 1000, 485, 1000, 0);
g .DrawLine(p, 0,480, 0, 0);
}
private void timer1_Tick(object sender, EventArgs e)
{
DoubleBuffered = false;
// int dx=3, dy=3, i = 300, o = 50;
i += dx;
if (i < 0)
{
dx = -dx;
}
else if (i + 50 > 1000)
{
dx = -dx;
}
o += dy;
if ((o +20>= rey) &&(i+20<=rex+200)&&(i+20>=rex))
{
//int rex = 400, rey = 450; RECTANGLE
// int dx=3, dy=3, i(x) = 500, o(y) = 100;
dy =-dy;
//c++;
//label1.Text = c.ToString();
}
// Misgeret\\
if (o < 0)
{
dy = -dy;
}
// Misgeret\\
else if (o + 50 > 600)
{
dy = -dy;
}
this.Invalidate();
}
private void label1_Click(object sender, EventArgs e)
{
label1.Text = c.ToString();
}
}
}
I noticed that you are setting DoubleBuffered to false in multiple areas of your program. That is definitely not helping since the whole reason to use double buffering is to prevent flickering.
The other thing is you are creating Graphics contexts and drawing in multiple places in your application. Try to refactor your code to only draw in the OnPaint() event handler of the form, and do not create a new Graphics context. Use the one provided in the PaintEventArgs of the OnPaint() event.
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
using(Brush green = new SolidBrush(Color.Green))
{
g.FillRectangle(green, rex, rey, 200, 20);
}
// .. etc, etc..
}
Then, when you need to the form to be repainted you just need to invoke the Invalidate() method to tell the GDI that your form, or a portion of it, needs to be repainted. That will in turn cause the Paint event to be fired and the OnPaint() to be called.
As a side note, as #HighCore suggested in the comments, WinForms is definitely not the right framework to create a game in. For games try the XNA framework, or one of several open source ones available on the web such as Unity
UPDATE
To prevent flickering you can use automatic double buffering for your form. This can be enabled in the form constructor, after the call to InitializeComponent(), using a call to SetStyle:
SetStyle( ControlStyles.AllPaintingInWmPaint
| ControlStyles.UserPaint
| ControlStyles.DoubleBuffer , true);

Draw rectangle C# Mouse_down working Mouse_up not

I want to draw an rectangle on an form the mouse_down event is working fine, but how do i programm the mouse_up. Should how do i dertermine the starting coordinates.
http://oi49.tinypic.com/2wcnof8.jpg
Rectangle rect = new Rectangle();
Color rastercolor = Color.Black;
private void drawGrid(Color rastercolor)
{
Graphics gfx = this.CreateGraphics();
Pen pen = new Pen(rastercolor);
for (int i = 0; i <= 2000; i = i + 20)
{
gfx.DrawLine(pen, 0, i, 2000, i);
}
for (int x = 0; x < 2000; x = x + 20)
{
gfx.DrawLine(pen, x, 0, x, 2000);
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
rect = new Rectangle(e.X, e.Y, 0, 0);
if (e.Button == MouseButtons.Middle)
{
ColorDialog coldial = new ColorDialog();
coldial.ShowDialog();
Color rastercolor = coldial.Color;
tekenGrid(rastercolor);
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
rect = new Rectangle(rect.Left, rect.Top, e.X - rect.Left, e.Y - rect.Top);
}
}
protected override void OnPaint(PaintEventArgs e)
{
tekenGrid(rastercolor);
using (Pen pen = new Pen(Color.Red, 2))
{
e.Graphics.DrawRectangle(pen, rect);
}
}
private void Frm1_MouseUp(object sender, MouseEventArgs e)
{
Graphics g = this.CreateGraphics();
Pen pen = new Pen(Color.Red, 2);
g.DrawRectangle(pen, rect);
}
private void Frm1_Load(object sender, EventArgs e)
{
}
private void Frm1_MouseDown(object sender, MouseEventArgs e)
{
Graphics g = this.CreateGraphics();
Pen pen = new Pen(Color.Blue, 2);
g.DrawRectangle(pen, rect);
}
}
}
Any help would be greatly appreciated,
Not sure if this is what you are upto. Please try this code.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.DoubleBuffered = true;
}
Rectangle rect = new Rectangle();
Color _rastercolor = Color.Black;
private Pen _pen=new Pen(Color.Red,2);
private void tekenGrid(Color rastercolor, Graphics gfx)
{
Pen pen = new Pen(rastercolor);
for (int i = 0; i <= 2000; i = i + 20)
{
gfx.DrawLine(pen, 0, i, 2000, i);
}
for (int x = 0; x < 2000; x = x + 20)
{
gfx.DrawLine(pen, x, 0, x, 2000);
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
rect = new Rectangle(e.X, e.Y, 0, 0);
if (e.Button == MouseButtons.Middle)
{
ColorDialog coldial = new ColorDialog();
coldial.ShowDialog();
Color rastercolor = coldial.Color;
tekenGrid(rastercolor,this.CreateGraphics());
}
else
base.OnMouseDown(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
rect = new Rectangle(rect.Left, rect.Top, e.X - rect.Left, e.Y - rect.Top);
this.Refresh();
}
base.OnMouseMove(e);
}
protected override void OnPaint(PaintEventArgs e)
{
tekenGrid(_rastercolor,e.Graphics);
e.Graphics.DrawRectangle(_pen, rect);
}
private void Frm1_MouseUp(object sender, MouseEventArgs e)
{
_pen = new Pen(Color.Red, 2);
this.Refresh();
}
private void Frm1_Load(object sender, EventArgs e)
{
}
private void Frm1_MouseDown(object sender, MouseEventArgs e)
{
_pen = new Pen(Color.Blue, 2);
}
}

picture box invalidate method in C#

I want to draw something in a picture box and remove them.
in this case i need to draw a fill circle and after a time remove it and draw a circle without fill it.
i use below code but when i want to remove a shape i need to draw picturebox another time with new shape and it causes a sensitive change in picture box.now i know i should use invalidate() method. but i do not know where and how should i use that.
void pbmapDo()
{
Graphics graphicPBMap = pbMap.CreateGraphics();
// usually Values : gridNeedUpdate = true; rulersNeedUpdate = true; rulerNeedUpdate = true; backGroundNeedUpdate = true; nodesNeedUpdate = true;
if (backGroundNeedUpdate)
{
Bitmap srce = new Bitmap(BackGround);
Bitmap dest = new Bitmap(pbMap.Width, pbMap.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
Graphics gr = Graphics.FromImage(dest);
gr.DrawImage(srce, new Rectangle(Point.Empty, dest.Size));
graphicPBMap.DrawImage(dest, 0, 0);
}
backGroundNeedUpdate = false;
if (isGridShow && gridNeedUpdate)
{
for (int i = 0; i < pbMap.Width / 60 + 1; i++)
{
graphicPBMap.DrawLine(gridPen, pbMap.Width - i * 60, 0, pbMap.Width - i * 60, pbMap.Height);
}
for (int i = 0; i < pbMap.Height / 60 + 1; i++)
{
graphicPBMap.DrawLine(gridPen, pbMap.Width, i * 60, 0, i * 60);
}
}
gridNeedUpdate = false;
if (isShowRulers && rulersNeedUpdate )
{
graphicPBMap.DrawLine(new Pen(Brushes.Black, 46), pbMap.Width - 1, pbMap.Height - 1, 0 - 1, pbMap.Height - 1);
graphicPBMap.DrawLine(new Pen(Brushes.Black, 49), 0, 0, 0, pbMap.Height);
for (int i = 0; i < pbMap.Width / 60 + 1; i++)
{
graphicPBMap.DrawString(XPixelToLong((double)pbMap.Width - i * 60).ToString(), new Font("Tahoma", 7), Brushes.White, pbMap.Width - i * 60, pbMap.Height - 15);
graphicPBMap.DrawLine(gridPen, pbMap.Width - i * 60, pbMap.Height - 24, pbMap.Width - i * 60, pbMap.Height);
}
for (int i = 0; i < pbMap.Height / 60 + 1; i++)
{
graphicPBMap.DrawLine(gridPen, 0, i * 60, 25, i * 60);
graphicPBMap.DrawString(YPixelToLat(i * 60).ToString(), new Font("Tahoma", 7), Brushes.White, 0, i * 60);
}
}
rulersNeedUpdate = false;
if (rulerNeedUpdate)
{
if (x0ruler != -1 && y0ruler != -1)
{
if (x1ruler != -1 && y1ruler != -1)
{
Rectangle rectAngle = new Rectangle((int)(x1ruler - 1), (int)(y1ruler - 1), 2, 2);
graphicPBMap.DrawEllipse(rulerPen, rectAngle);
graphicPBMap.DrawLine(rulerPen, x0ruler, y0ruler, x1ruler, y1ruler);
rectAngle = new Rectangle((int)(x0ruler - 1), (int)(y0ruler - 1), 2, 2);
graphicPBMap.DrawEllipse(rulerPen, rectAngle);
}
else
{
Rectangle rectAngle = new Rectangle((int)(x0ruler - 1), (int)(y0ruler - 1), 2, 2);
graphicPBMap.DrawEllipse(rulerPen, rectAngle);
}
}
}
rulerNeedUpdate = false;
if (nodesNeedUpdate)
{
nodesNeedUpdate = false;
Node node;
for (int i = 0; i < nodes.Count; i++)
{
node = (Node)(nodes[i]);
if (node.IsOn)
{
drawOnCircle(graphicPBMap,node.Longitude, node.Latitude, node.RInMeter, node.IsSelected);
}
else
{
drawOffCircle(graphicPBMap, node.Longitude, node.Latitude, node.RInMeter, node.IsSelected);
}
}
}
}
EDIT 1 :
i changed code once.
You can use
invalidate() or pictureBox.image = null; where you need to change the image of your picturebox.
Anyway, it is not required to change the background always. Instead you can make your bitmap and place it as pictureBox.Image = bitmap.
If you need exact sample source code let me know.
sorry for the late.
try this
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Bitmap bckMap = null;
private void Form1_Load(object sender, EventArgs e)
{
bckMap = new Bitmap(this.pictureBox1.Width, this.pictureBox1.Height);
using (Graphics g = Graphics.FromImage(bckMap))
{
g.FillRectangle(new SolidBrush(Color.Black), new Rectangle(0, 0, bckMap.Width, bckMap.Height));
g.Dispose();
}
pictureBox1.BackgroundImage = bckMap;
}
private void button2_Click(object sender, EventArgs e)
{
pictureBox1.Image = null;
Bitmap ellips = new Bitmap(this.pictureBox1.Width, this.pictureBox1.Height);
using (Graphics g = Graphics.FromImage(ellips))
{
g.FillEllipse(new SolidBrush(Color.Red), new Rectangle(0, 0, ellips.Width, ellips.Height));
g.Dispose();
}
this.pictureBox1.Image = ellips;
}
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.Image = null;
Bitmap ellips = new Bitmap(this.pictureBox1.Width, this.pictureBox1.Height);
using (Graphics g = Graphics.FromImage(ellips))
{
g.FillRectangle(new SolidBrush(Color.Green), new Rectangle(5, 5, ellips.Width-10, ellips.Height-10));
g.Dispose();
}
this.pictureBox1.Image = ellips;
}
I finally find a solution.
I need to use paint event of picture box.
private void pbMap_Paint(object sender, PaintEventArgs e)
{
//do every think you want with picture box like draw circle or change background
}
in this event i put every think i want to do with pbMap picture box.
and when i changed some i call below function to apply my changes,
public void updateMap()
{
if (pbMap.InvokeRequired) // just if you call in thread
{
pbMap.Invoke(new Action(() => pbMap.Invalidate()));
}
else
{
pbMap.Invalidate();
}
}

Categories

Resources