I am trying to make my picturebox move across the screen but I have this error: 'picture' does not exist in the current context inside the timer. What can I do?
private void Button1_Click(object sender, EventArgs e)
{
var picture = new PictureBox
{
Name = "pictureBox",
Size = new Size(20, 20),
Location = new System.Drawing.Point(x, y),
Image = image1,
};
this.Controls.Add(picture);
timer1.Enabled = true;
}
private void Timer1_Tick(object sender, EventArgs e)
{
//redefine pictureBox position.
x = x - 50;
picture.Location = new System.Drawing.Point(x, y); //'picture' does not exist in the current context
}
Well, picture is a local variable and thus is not visible outside Button1_Click. Let's turn it into a field:
// now picture is a private field, visible within th class
//TODO: do not forget to Dispose it
private PictureBox picture;
private void Button1_Click(object sender, EventArgs e)
{
if (picture != null) // already created
return;
picture = new PictureBox
{
Name = "pictureBox",
Size = new Size(20, 20),
Location = new System.Drawing.Point(x, y),
Image = image1,
Parent = this, // instead of this.Controls.Add(picture);
};
timer1.Enabled = true;
}
private void Timer1_Tick(object sender, EventArgs e)
{
//redefine pictureBox position.
x = x - 50;
if (picture != null) // if created, move it
picture.Location = new System.Drawing.Point(x, y);
}
Try putting the picture outside of the button click like this:
PictureBox picture;
private void Button1_Click(object sender, EventArgs e)
{
picture = new PictureBox
{
Name = "pictureBox",
Size = new Size(20, 20),
Location = new System.Drawing.Point(x, y),
Image = image1,
};
this.Controls.Add(picture);
timer1.Enabled = true;
}
private void Timer1_Tick(object sender, EventArgs e)
{
//redefine pictureBox position.
x = x - 50;
if(picture != null)
picture.Location = new System.Drawing.Point(x, y);
}
Related
I have a program which dynamically creates movable pictureboxes when I click on buttons. I need to do something like when I click on the picturebox, this click adds to my dynamically created picturebox a new textbox when I can write descripiton of this picturebox(name,...). This textbox should be able to move with picturebox.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
List<PictureBox> pictureboxes = new List<PictureBox>();
public Form1()
{
InitializeComponent();
}
private void AddPictureBox(string imagePath)
{
var pb = new PictureBox();
pb.Name = "picturebox" + pictureboxes.Count;
pb.Location = new Point(pictureboxes.Count * 100, 100);
pb.Size = new Size(70, 70);
pb.BorderStyle = BorderStyle.None;
pb.SizeMode = PictureBoxSizeMode.StretchImage;
this.Controls.Add(pb);
pb.Image = Image.FromFile(imagePath);
pb.Refresh();
pb.MouseDown += new MouseEventHandler(picMouseDown);
pb.MouseMove += new MouseEventHandler(picMouseMove);
pb.MouseUp += new MouseEventHandler(picMouseUp);
pictureboxes.Add(pb);
Invalidate();
}
private void router_Click(object sender, EventArgs e)
{
AddPictureBox(#"D:\\router.jpg");
}
private void Form1_Load(object sender, EventArgs e)
{
}
int x = 0;
int y = 0;
bool drag = false;
private void picMouseDown(object sender, MouseEventArgs e)
{
// Get original position of cursor on mousedown
x = e.X;
y = e.Y;
drag = true;
}
private void picMouseMove(object sender, MouseEventArgs e)
{
if (drag)
{
PictureBox pb = (PictureBox)sender;
// Get new position of picture
pb.Top += e.Y - y;
pb.Left += e.X - x;
pb.BringToFront();
Invalidate();
}
}
private void picMouseUp(object sender, MouseEventArgs e)
{
drag = false;
}
private void switch1_Click(object sender, EventArgs e)
{
AddPictureBox(#"D:\HP ProBook 450\Desktop\Grafika\switch1.png");
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
private void pc_Click(object sender, EventArgs e)
{
AddPictureBox(#"D:\HP ProBook 450\Desktop\pc.jpg");
}
private void server_Click(object sender, EventArgs e)
{
AddPictureBox(#"D:\HP ProBook 450\Desktop\server.png");
}
}
Thanks for any help :).
You can add a TextBox to a PictureBox in code like this:
TextBox newTextBox = new TextBox();
newTextBox.Parent = yourPictureBox;
// place it e.g. to the left bottom:
newTextBox.Location = new Point(10, yourPictureBox.Height - newTextBox.Height);
Note that this will add the TextBox to the Controls collection of the PB; so it will sit on top of the PictureBox; so, yes, it will move with the PictureBox but it will also hide a part or the PB!
If instead you simply want to group them, add them both to something like a Panel, again by setting that as their Parent!
Also note that you can't do this in the Designer; PictureBox is not really meant to act as a Container..
It doesn't matter how the PictureBox was created, as long as you have a reference to it.
i am developing a system which allow user to drag objects around within a same panel, i went through some research and founds that i should use mouse events like mouse_up, mouse_down and mouse_move.
The the program will generate 3 picturebox and allow the user to drag around the every picturebox within the panel, but the program i code did not work perfectly as when i drag over a picturebox, the picturebox will move, but not according to my mouse cursor location, it is somewhere else, besides, when dragging, there is picturebox shadows in the panel, i've tried those update(),refresh(), and invalidate() but it seems not useful for me. Below are my codes, thanks for helping
public partial class Form1 : Form
{
List<PictureBox> pictureBoxList = new List<PictureBox>();
private bool isDragging = false;
public Form1()
{
InitializeComponent();
for (int i = 0; i < 3; i++)
{
PictureBox picture = new PictureBox
{
Name = "pictureBox" + i,
Size = new Size(20, 20),
Location = new Point(i * 40, i * 40),
BorderStyle = BorderStyle.FixedSingle,
SizeMode = PictureBoxSizeMode.Zoom,
ImageLocation = "A.jpg"
};
pictureBoxList.Add(picture);
foreach (PictureBox p in pictureBoxList)
{
p.MouseDown += new MouseEventHandler(c_MouseDown);
p.MouseMove += new MouseEventHandler(c_MouseMove);
p.MouseUp += new MouseEventHandler(c_MouseUp);
pnlDisplayImage.Controls.Add(p);
pnlDisplayImage.Refresh();
}
}
}
void c_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
}
void c_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging == true) {
Control c = sender as Control;
for (int i = 0; i < pictureBoxList.Count(); i++)
{
if (c.Equals(pictureBoxList[i]))
{
pictureBoxList[i].Location = new Point(e.X, e.Y);
}
}
}
}
void c_MouseUp(object sender, MouseEventArgs e)
{
PictureBox c = sender as PictureBox;
isDragging = false;
for (int i = 0; i < pictureBoxList.Count(); i++) {
if (c.Equals(pictureBoxList[i])){
pictureBoxList[i].Location = new Point(e.X, e.Y);
}
}
}
private void pnlDisplayImage_Paint(object sender, PaintEventArgs e)
{
foreach (PictureBox p in pictureBoxList)
{
pnlDisplayImage.Controls.Add(p);
}
}
}
Finally I've found what are the problems that caused my program not running as my expectations. The main problem is that I accidentally put the foreach loop inside the for loop which I used to create pictureBox, this problem caused the pictureBox comes out some shadows effect while dragging during run time due to there are few same pictureBox. Also, I have change a little bit of the codes and it now run as what I expected. Below are the code that I want for answer.
public partial class Form1 : Form
{
List<PictureBox> pictureBoxList = new List<PictureBox>();
private bool isDragging = false;
Point move;
public Form1()
{
InitializeComponent();
for (int i = 0; i < 3; i++)
{
PictureBox picture = new PictureBox
{
Name = "pictureBox" + i,
Size = new Size(20, 20),
Location = new Point(i * 40, i * 40),
BorderStyle = BorderStyle.FixedSingle,
SizeMode = PictureBoxSizeMode.Zoom,
ImageLocation = "A.jpg"
};
pictureBoxList.Add(picture);
}
foreach (PictureBox p in pictureBoxList)
{
p.MouseDown += new MouseEventHandler(c_MouseDown);
p.MouseMove += new MouseEventHandler(c_MouseMove);
p.MouseUp += new MouseEventHandler(c_MouseUp);
pnlDisplayImage.Controls.Add(p);
pnlDisplayImage.Refresh();
}
}
void c_MouseDown(object sender, MouseEventArgs e)
{
Control c = sender as Control;
isDragging = true;
move = e.Location;
}
void c_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging == true) {
Control c = sender as Control;
for (int i = 0; i < pictureBoxList.Count(); i++)
{
if (c.Equals(pictureBoxList[i]))
{
pictureBoxList[i].Left += e.X - move.X;
pictureBoxList[i].Top += e.Y - move.Y;
}
}
}
}
void c_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
}
Try something like (it's custom control with overrides, but should be easy to convert to events):
private bool _isMoved = false; // true if move mode on
private Point _pointMove = new Point(0); // for moving
protected override void OnMouseDown(MouseEventArgs e)
{
// if left button pressed
if(e.Button == MouseButtons.Left)
{
_pointMove.X = e.X;
_pointMove.Y = e.Y;
_isMoved = true;
Cursor = Cursors.SizeAll;
Capture = true;
}
base.OnMouseDown (e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
// if move mode on
if(_isMoved)
{
_isMoved = false;
Cursor = Cursors.Default;
Capture = false;
}
base.OnMouseUp (e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
// if move mode on
if (_isMoved)
{
Left += e.X - _pointMove.X;
Top += e.Y - _pointMove.Y;
}
base.OnMouseMove (e);
}
I'm trying to save the contents of a PictureBox to a database. This in itself works well, however once the signature picture box has been drawn on, it is not setting the PictureBox.Image property, meaning I can't continue with the process.
Pen myPen;
bool bMouseDown = false;
Point prevPoint;
Graphics gCust;
Graphics gTech;
private void NewJob_Load(object sender, EventArgs e)
{
myPen = new System.Drawing.Pen(System.Drawing.Color.Black);
gCust = pbCustomerSig.CreateGraphics();
gCust.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
myPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
myPen.SetLineCap(LineCap.Round, LineCap.Round, DashCap.Round);
myPen.Color = Color.Blue;
myPen.Width = 2f;
}
public static byte[] ImageToBinary(Image image)
{
Byte[] buffer = (Byte[])new ImageConverter().ConvertTo(image, typeof(Byte[]));
return buffer;
}
private void pbCustomerSig_MouseDown(object sender, MouseEventArgs e)
{
prevPoint = e.Location;
bMouseDown = true;
}
private void pbCustomerSig_MouseMove(object sender, MouseEventArgs e)
{
if (bMouseDown)
{
Point thisPoint = e.Location;
if (prevPoint.X == 0 && prevPoint.Y == 0)
{
prevPoint = thisPoint;
return;
}
gCust.DrawLine(myPen, thisPoint.X, thisPoint.Y, prevPoint.X, prevPoint.Y);
prevPoint = thisPoint;
}
}
private void pbCustomerSig_MouseUp(object sender, MouseEventArgs e)
{
bMouseDown = false;
}
The error is here -
h.CustomerSignature = ImageToBinary(pbCustomerSig.Image);
Any ideas why the PictureBox.Image property is null?
Many thanks!
You did not assign a value for pbCustomerSig.Image. It's normal to be null.
Instead of doing that try to draw into a bitmap.
Here is a sample for drawing on existing bitmap but you can draw on a empty bitmap with same way and show it on picturebox at the same time.
I want to deleting image inside picturebox ( its autogenerated) that selected mouse click, So I can delete it with delete key or maybe contextmenu...
Here the code:
private void button1_Click(object sender, EventArgs e)
{
string theimage = AppDomain.CurrentDomain.BaseDirectory + #"allimages";
string[] images = Directory.GetFiles(theimage, "*.png");
int aa;
for (aa = 1; aa < images.Count(); aa++)
{
PictureBox myPicBox = new PictureBox();
myPicBox.Location = new Point(7, 240);
myPicBox.Width = 100;
myPicBox.Height = 77;
myPicBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
myPicBox.Margin = new Padding(3, 3, 3, 3);
myPicBox.Visible = true;
myPicBox.Image = new Bitmap(images[aa]);
this.flowLayoutPanel1.Controls.Add(myPicBox);
//myPicBox.Click += new EventHandler(curPb_Click);
//myPicBox.MouseUp += new MouseEventHandler(myPicBox_MouseUp);
myPicBox.MouseDown += new MouseEventHandler(myPicBox_MouseDown);
myPicBox.MouseLeave += new EventHandler(mmm_Leave);
}
}
//private PictureBox senderAsPictureBox = null;
private void mmm_Leave(object sender, EventArgs e)
{
PictureBox senderAsPictureBox = sender as PictureBox;
senderAsPictureBox.BackColor = Color.Empty;
}
private void myPicBox_MouseDown(object sender, MouseEventArgs e)
{
PictureBox senderAsPictureBox = sender as PictureBox;
MessageBox.Show(senderAsPictureBox.ToString());
senderAsPictureBox.BackColor = Color.AliceBlue;
}
Here what I want to do
LOGIC:
User selecting image thumb inside picturebox -> When USER press [delete] keys -> delete the selected image
I don't get your problem.
If you want to clear it use this:
senderAsPictureBox.Image = null;
senderAsPictureBox.Invalidate();
EDIT:
After you set the image, set the name of the control to the imagepath:
myPicBox.Name = images[aa].ToString();
Also create a new Eventhandler to handle your KeyDownEvent
myPicBox.PreviewKeyDown += new reviewKeyDownEventHandler(myPicBox_PreviewKeyDown);
With this method:
void myPicBox_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
PictureBox senderAsPictureBox = sender as PictureBox;
File.Delete(senderAsPictureBox.Name);
}
In your MouseDownHandlerMethod focus your control with:
senderAsPictureBox.Focus();
Found solution from here Get Picturebox Path and SubNatural answers
So, I'll leave the code here for who may need it
private void button1_Click(object sender, EventArgs e)
{
string theimage = AppDomain.CurrentDomain.BaseDirectory + #"allimages";
string[] images = Directory.GetFiles(theimage, "*.png");
int aa;
for (aa = 1; aa < images.Count(); aa++)
{
PictureBox myPicBox = new PictureBox();
myPicBox.Location = new Point(7, 240);
myPicBox.Width = 100;
myPicBox.Height = 77;
myPicBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
myPicBox.Margin = new Padding(3, 3, 3, 3);
myPicBox.Visible = true;
FileStream fs = new FileStream(images[aa], FileMode.Open, FileAccess.Read);
myPicBox.Image = Image.FromStream(fs);
myPicBox.Name = images[aa];
fs.Close();
this.flowLayoutPanel1.Controls.Add(myPicBox);
//myPicBox.Click += new EventHandler(curPb_Click);
//myPicBox.MouseUp += new MouseEventHandler(myPicBox_MouseUp);
myPicBox.MouseDown += new MouseEventHandler(myPicBox_MouseDown);
myPicBox.MouseLeave += new EventHandler(mmm_Leave);
myPicBox.PreviewKeyDown += new PreviewKeyDownEventHandler(myPicBox_PreviewKeyDown);
}
}
private void myPicBox_MouseDown(object sender, MouseEventArgs e)
{
PictureBox senderAsPictureBox = sender as PictureBox;
senderAsPictureBox.Focus(); // binding for clicking
senderAsPictureBox.BackColor = Color.AliceBlue;
}
void myPicBox_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
PictureBox senderAsPictureBox = sender as PictureBox;
if (e.KeyCode == Keys.Delete)
senderAsPictureBox.Image = null;
senderAsPictureBox.Invalidate();
senderAsPictureBox.Dispose();
File.Delete(senderAsPictureBox.Name);
}
Thanks for everyone for helping me... :) especially for #SubNatural
My current code allows me to draw rectangles from a user defined spot but not in the way in whihc i desire. I need it to be like you would do it in paint, here is my current code:
namespace SimpleDraw2
{
///
/// Description of MainForm.
///
public partial class MainForm : Form
{
bool IsMouseDown = false;
Point MousePosition;
int DrawShape = 0;
Bitmap StoredImage;
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
//
// TODO: Add constructor code after the InitializeComponent() call.
//
pictureBox1.Image = new Bitmap (pictureBox1.Width,pictureBox1.Height);
StoredImage = new Bitmap(pictureBox1.Width,pictureBox1.Height);
}
void PictureBox1MouseDown(object sender, MouseEventArgs e)
{
IsMouseDown = true;
MousePosition = e.Location;
Graphics gStored = Graphics.FromImage(StoredImage);
gStored.Clear(Color.Transparent);
gStored.DrawImage(pictureBox1.Image, 0, 0);
}
void PictureBox1MouseUp(object sender, MouseEventArgs e)
{
IsMouseDown = false;
}
void PictureBox1MouseMove(object sender, MouseEventArgs e)
{
Graphics g = Graphics.FromImage(pictureBox1.Image);
if (DrawShape == 0)
{
Pen p = new Pen(Color.Red, 10);
if (IsMouseDown)
{
g.DrawLine(p,MousePosition,e.Location);
MousePosition = e.Location;
}
}
if (DrawShape == 1)
{
g.Clear(Color.Transparent);
g.DrawImage(StoredImage,0,0);
g.DrawRectangle(Pens.Green,MousePosition.X,MousePosition.Y,e.X,e.Y);
}
if (DrawShape == 2)
{
g.Clear(Color.Transparent);
g.DrawImage(StoredImage, 0, 0);
g.DrawEllipse(Pens.HotPink, MousePosition.X, MousePosition.Y, e.X, e.Y);
}
if (DrawShape == 3)
{
g.Clear(Color.Transparent);
g.DrawImage(StoredImage, 0, 0);
g.DrawArc(Pens.Indigo,pictureBox1.Bounds, e.Y, e.X);
}
//if (DrawShape == 4)
//{
// g.Clear(Color.Transparent);
// g.DrawImage(StoredImage, 0, 0);
// g.DrawPolygon(Pens.Indigo, Point[] e.X);
//}
this.Refresh();
}
private void button2_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
axWindowsMediaPlayer1.URL = ofd.FileName;
}
}
private void button1_Click(object sender, EventArgs e)
{
axWindowsMediaPlayer1.Ctlcontrols.pause();
Bitmap bmp = new Bitmap(axWindowsMediaPlayer1.Width, axWindowsMediaPlayer1.Height);
Graphics gfx = Graphics.FromImage(bmp);
gfx.CopyFromScreen(PointToScreen(axWindowsMediaPlayer1.Location), new Point(0, 0), axWindowsMediaPlayer1.Bounds.Size, CopyPixelOperation.SourceCopy);
pictureBox1.BackgroundImage = bmp;
//axWindowsMediaPlayer1.Visible = false;
//pictureBox1.Visible = true;
}
private void button3_Click(object sender, EventArgs e)
{
Graphics gg = Graphics.FromImage(pictureBox1.BackgroundImage);
gg.Clear(Color.Transparent);
Graphics gStored = Graphics.FromImage(StoredImage);
gStored.Clear(Color.Transparent);
Graphics g = Graphics.FromImage(pictureBox1.Image);
g.Clear(Color.Transparent);
}
private void button4_Click(object sender, EventArgs e)
{
DrawShape = 1;
}
private void button6_Click(object sender, EventArgs e)
{
DrawShape = 2;
}
private void button8_Click(object sender, EventArgs e)
{
DrawShape = 3;
}
private void button7_Click(object sender, EventArgs e)
{
DrawShape = 0;
}
}
}
If someone could help me edit my code to iron out the issue to make it easy drag and draw system it would me much appreciate.
Thanks in Advance
Chris
From msdn:
Draws a rectangle specified by a
coordinate pair, a width, and a
height.
So your code won't work:
g.DrawRectangle(Pens.Green,MousePosition.X,MousePosition.Y,e.X,e.Y);
Should be something like
g.DrawRectangle(Pens.Green, MousePosition.X, MousePosition.Y, Math.Abs(e.X - MousePosition.X), Math.Abs(e.Y - MousePosition.Y));
The biggest problem I see is that you're trying to draw in the mouse events. This means your drawing will be wiped away the instant you get a refresh event.
Only draw in Paint events, never in mouse events. If you want your app to draw as a result of mouse events, set a point, rectangle, or whatever in the mouse events (like you start to do with IsMouseDown), invalidate the area you want to change in your MouseMoved event, then draw your rectangle or whatever in your Paint event.