I'd like to run a piece of code which keeps changing the picture of a picturebox (like a rotating propeller) until the form is closed.
I managed to change the picture of the PictureBox with an EventHandler, but I don't know how to go along.
public Form1()
{
InitializeComponent();
this.Controls.Add(pb);
}
PictureBox pb = new PictureBox
{
Location = new Point(0, 0),
SizeMode = PictureBoxSizeMode.Zoom,
Size = new Size(300,300),
ImageLocation = #"E:\folder\gas_jo.png"
};
private void Form1_Click(object sender, EventArgs e)
{
if (pb.ImageLocation == #"E:\folder\gas_jo.png")
{
pb.ImageLocation =#"E:\folder\gas_jo_1.png";
}
else if (pb.ImageLocation == #"E:\folder\gas_jo_1.png")
{
pb.ImageLocation = #"E:\folder\gas_jo.png";
}
}
System.Windows.Forms.Timer timer;
public Form1()
{
InitializeComponent();
this.Controls.Add(pb);
timer = new System.Windows.Forms.Timer();
timer.Interval = 1000;
timer.Tick += (sender, args) => {
if (pb.ImageLocation == #"E:\folder\gas_jo.png")
{
pb.ImageLocation =#"E:\folder\gas_jo_1.png";
}
else if (pb.ImageLocation == #"E:\Real-time_Imi\gas_jo_1.png")
{
pb.ImageLocation = #"E:\Real-time_Imi\gas_jo.png";
}
};
timer.Start();
}
PictureBox pb = new PictureBox
{
Location = new Point(0, 0),
SizeMode = PictureBoxSizeMode.Zoom,
Size = new Size(300,300),
ImageLocation = #"E:\folder\gas_jo.png"
};
string[] pictureBoxArray = new string[] { #"E:\folder\gas_jo.png", #"E:\folder\gas_jo_1.png", #"E:\folder\gas_jo_2.png" };
int pctIndex = 0;
private void timer1_Tick(object sender, EventArgs e)
{
pb.ImageLocation = pictureBoxArray[pctIndex];
pctIndex ++;
if(pctIndex==pictureBoxArray.Length)
pctIndex =0 ;
}
Related
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);
}
In my code, every time button1 is pressed an instance of a picturebox called NOT is spawned in a panel. When the image is clicked and held on it can be dragged around. My question is every time button1 is pressed I want another pictureBox of the same properties to be created so that theoretically I could press button1 all day and drag around as many NOT picturebox objects around as I want. So far once the button is pressed only one instance of NOT is created and another cannot be spawned. So essentially how do make new unique instances of NOT every time button1 is pressed.
public Form1()
{
InitializeComponent();
Drag();
}
private void button1_Click(object sender, EventArgs e)
{
spawnGate("not");
}
PictureBox NOT = new PictureBox();
private Point startPoint = new Point();
public void Drag()
{
NOT.MouseDown += (ss, ee) =>
{
if (ee.Button == System.Windows.Forms.MouseButtons.Left)
{
startPoint = Control.MousePosition;
}
};
NOT.MouseMove += (ss, ee) =>
{
if (ee.Button == System.Windows.Forms.MouseButtons.Left)
{
Point temp = Control.MousePosition;
Point res = new Point(startPoint.X - temp.X, startPoint.Y - temp.Y);
NOT.Location = new Point(NOT.Location.X - res.X, NOT.Location.Y - res.Y);
startPoint = temp;
}
};
}
public void spawnGate(string type)
{
switch (type)
{
case "not":
NOT.Width = 100;
NOT.Height = 50;
NOT.Image = Properties.Resources.Not_gate;
NOT.SizeMode = PictureBoxSizeMode.Zoom;
workspace.Controls.Add(NOT);
break;
}
}
}
Change NOT to a List<PictureBox>.
Then, add a new PictureBox instance to NOT in the spawnGate() method. Note that Drag() will need to be changed to take a PictureBox argument.
Edit: As requested in the comments, for the benefit of others visiting this question, here is exactly how the code would need to be changed to get the behavior requested by OP. Note that this design could and should be refactored in a few areas.
List<PictureBox> NOT = new List<PictureBox>();
Point startPoint = new Point();
public Form1()
{
InitializeComponent();
Drag();
}
private void button1_Click(object sender, EventArgs e)
{
spawnGate();
}
public void spawnGate()
{
var pictureBox = new PictureBox()
{
Width = 100,
Height = 50,
Image = Properties.Resources.Not_gate,
SizeMode = PictureBoxSizeMode.Zoom
}
Drag(pictureBox);
NOT.Add(pictureBox);
workspace.Controls.Add(pictureBox);
}
public void Drag(PictureBox pictureBox)
{
pictureBox.MouseDown += (ss, ee) =>
{
if (ee.Button == System.Windows.Forms.MouseButtons.Left)
startPoint = Control.MousePosition;
};
pictureBox.MouseMove += (ss, ee) =>
{
if (ee.Button == System.Windows.Forms.MouseButtons.Left)
{
Point temp = Control.MousePosition;
Point res = new Point(startPoint.X - temp.X, startPoint.Y - temp.Y);
pictureBox.Location = new Point(pictureBox.Location.X - pictureBox.X, pictureBox.Location.Y - res.Y);
startPoint = temp;
}
};
}
You don't have to save the pointer to NOT on the form directly (or you could save them to a list if you need to call them at a later point).
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
spawnGate("not");
}
// This list is optional, if you easily want to find them later
List<PictureBox> allNOTs = new List<PictureBox>();
public void spawnGate(string type)
{
switch (type)
{
case "not":
PictureBox NOT = new PictureBox();
NOT.Width = 100;
NOT.Height = 50;
NOT.Image = Properties.Resources.Not_gate;
NOT.SizeMode = PictureBoxSizeMode.Zoom;
NOT.MouseDown += (ss, ee) =>
{
// Mouse down event code here
};
NOT.MouseMove += (ss, ee) =>
{
// Mouse move event code here
};
allNOTS.Add(NOT); // Optional if you easily want to find it later
workspace.Controls.Add(NOT);
break;
}
}
}
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 make a slideshow with a mediaElement that shows each image in listbox x seconds.
How do I make my code play each image x seconds before continuing?
This code adds all images to a listbox named Listbox1
Dictionary<string, string> Listbox1Dict = new Dictionary<string, string>();
private void SearchBtn_Click(object sender, RoutedEventArgs e)
{
Listbox1.Items.Clear();
FolderBrowserDialog folderDialog = new FolderBrowserDialog();
folderDialog.SelectedPath = "C:\\";
DialogResult result = folderDialog.ShowDialog();
if (result.ToString() == "OK")
FileNameTextBox.Text = folderDialog.SelectedPath;
string directory = FileNameTextBox.Text;
var files = Directory.GetFiles(directory).Where(name => !name.EndsWith(".ini"));
foreach (string file in files)
{
Listbox1.Items.Add(System.IO.Path.GetFileNameWithoutExtension(file));
Listbox1Dict.Add(System.IO.Path.GetFileNameWithoutExtension(file), file);
}
}
This code shows all images in fullscreen but it skips everyone to last image at start.
private void button1_Click_1(object sender, RoutedEventArgs e)
{
foreach (var selected in Listbox1.Items)
{
string s = selected.ToString();
if (Listbox1Dict.ContainsKey(s))
{
mediaElement1.Visibility = Visibility.Visible;
SearchBtn.Visibility = Visibility.Hidden;
Listbox1.Visibility = Visibility.Hidden;
FileNameTextBox.Visibility = Visibility.Hidden;
mediaElement1.Source = new Uri(Listbox1Dict[s]);
mediaElement1.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
mediaElement1.Height = System.Windows.SystemParameters.PrimaryScreenHeight;
this.Background = new SolidColorBrush(Colors.Black);
this.WindowStyle = WindowStyle.None;
this.WindowState = WindowState.Maximized;
}
}
}
Tried this code to make the image play one by one but I get an error. Look on comment on code:
private int currentSongIndex = -1;
void mediaElement1next(object sender, EventArgs e)
{
if(currentSongIndex == -1)
{
currentSongIndex = Listbox1.SelectedIndex;
}
currentSongIndex++;
if(currentSongIndex < Listbox1.Items.Count)
{
mediaElement1.Play(Listbox1.Items[currentSongIndex]); // No overload for method 'Play' takes 1 arguments
}
else
{
// last song in listbox has been played
}
}
I think you need a timer to set your next image. Using the code you're currently using, it will iterate through your list and change the image until you get to the end.
Take a look at DispatcherTimer. You could set it so, at each tick, it would change to the next image. Something like this (just writing off my head)
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
Then, inside your eventhandler:
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
// get the next image
}
Of course you can use other kinds of timers, but that's the main idea.
Hold your image paths in a list & use the tick event of a timer.
Something like:
List<string> paths = new List<string>();
private void timer1_Tick(object sender, EventArgs e)
{
pictureBox1.Image = getNextImage();
}
private string getNextImage()
{
//code...
}
enter code here
EDIT:
Add a class variable: int index = 0;
On the SearchBtn_Click event, add the results to the list.
//..
foreach (string file in files)
{
paths.Add(file);
}
//..
Then do as I did above and the content of the getNextImage method would be:
private string getNextImage()
{
if(index < paths.Count - 1)
{
index += 1;
}
else
{
index = 0;
}
return paths[index];
}
My idea would be to implement a thread that counted to X and then called a NextImage() function when done.
Something like this:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
if (Listbox1.Items.Count > 0)
{
if (dispatcherTimer.IsEnabled)
dispatcherTimer.Stop();
else
{
curImage = 0;
dispatcherTimer.Start();
}
}
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
Dispatcher.Invoke((Action)delegate
{
ShowNextImage();
}, null);
}
private void ShowNextImage()
{
if (curImage >= Listbox1.Items.Count)
curImage = 0;
var selected = Listbox1.Items[curImage];
string s = selected.ToString();
if (Listbox1Dict.ContainsKey(s))
{
mediaElement1.Visibility = Visibility.Visible;
SearchBtn.Visibility = Visibility.Hidden;
Listbox1.Visibility = Visibility.Hidden;
FileNameTextBox.Visibility = Visibility.Hidden;
mediaElement1.Source = new Uri(Listbox1Dict[s]);
mediaElement1.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
mediaElement1.Height = System.Windows.SystemParameters.PrimaryScreenHeight;
this.Background = new SolidColorBrush(Colors.Black);
this.WindowStyle = WindowStyle.None;
this.WindowState = WindowState.Maximized;
}
}
and declaration
DispatcherTimer dispatcherTimer = new DispatcherTimer();
int x = 2; //seconds
private int curImage = 0;
and some construct
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, x);
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