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
Related
I have an action for my button in c# Winform like this:
private void btnAction_Click(object sender, EventArgs e)
{
TextBox tbxdg = new TextBox();
tbxdg.Name = "tbx_DG" + cx.ToString();
tbxdg.Location = new Point(508, 12 + (40 * cx));
tbxdg.Size = new Size(200, 24);
tbxdg.Font = new Font("Tahoma", 10);
panel2.Controls.Add(tbxdg);
cx++;
}
Now I want to get text from the textbox that i've created by clicking my button. I've tried call the textbox by the name that i given to it in the button click action but it's not working.
u can try this:
var textBoxText = panel2.Controls.Find("name of textbox", false).First().Text;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private int cx = 0;
private void button1_Click(object sender, EventArgs e)
{
TextBox tbxdg = new TextBox();
tbxdg.Name = "tbx_DG" + cx.ToString();
tbxdg.Location = new Point(0, 0 + (40 * cx));
tbxdg.Size = new Size(200, 24);
tbxdg.Font = new Font("Tahoma", 10);
panel1.Controls.Add(tbxdg);
cx++;
}
private void button2_Click(object sender, EventArgs e)
{
label1.Text = string.Empty;
foreach (TextBox tb in panel1.Controls)
{
label1.Text += $"{tb.Name} - {tb.Text}\n";
}
}
}
Demo
Instead of searching the control name in the panel, another approach is to add all the dynamic text boxes to global List<TextBox>
Please read comments inside the example:
private int cx;
private List<TextBox> DynamicTextBoxesList = new List<TextBox>();
private void btnAction_Click(object sender, EventArgs e)
{
TextBox tbxdg = new TextBox();
tbxdg.Name = "tbx_DG" + cx.ToString();
tbxdg.Location = new Point(508, 12 + (40 * cx));
tbxdg.Size = new Size(200, 24);
tbxdg.Font = new Font("Tahoma", 10);
panel2.Controls.Add(tbxdg);
// add to list
DynamicTextBoxesList.Add(tbxdg);
cx++;
}
// button event for example how to use DynamicTextBoxesList
private void btnExampleFoaccesingTextBoxes_Click(object sender, EventArgs e)
{
if (DynamicTextBoxesList.Count > 0)
{
foreach (TextBox t in DynamicTextBoxesList)
{
MessageBox.Show(t.Text);
}
// or you can find by name for example you need cx=1:
var txtbox = DynamicTextBoxesList.Where(x => x.Name == "tbx_DG1").FirstOrDefault();
if (txtbox != null)
{
MessageBox.Show(txtbox.Text);
}
}
}
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);
}
I have 7 pictureboxes and I want to drag and drop each one of them. I have made the drag and drop but it takes with it the original picturebox which I drag it doesn't leave it on its place. This is my code:
this.pbAND.MouseDown += pictureBox_MouseDown;
pbAND.MouseMove += pictureBox_MouseMove;
pbAND.MouseUp += pictureBox_MouseUp;
this.pbOR.MouseDown += pictureBox_MouseDown;
pbOR.MouseMove += pictureBox_MouseMove;
pbOR.MouseUp += pictureBox_MouseUp;
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
p = (PictureBox)sender;
downPoint = e.Location;
var dragImage = (Bitmap)p.Image;
IntPtr icon = dragImage.GetHicon();
Cursor.Current = new Cursor(icon);
p.Parent = this;
p.BringToFront();
DestroyIcon(icon);
}
}
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
p = (PictureBox)sender;
if (e.Button == MouseButtons.Left)
{
p.Left += e.X - downPoint.X;
p.Top += e.Y - downPoint.Y;
}
}
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
p = (PictureBox)sender;
Control c = GetChildAtPoint(new Point(p.Left - 1, p.Top));
if (c == null) c = this;
Point newLoc = c.PointToClient(p.Parent.PointToScreen(p.Location));
p.Parent = c;
p.Location = newLoc;
}
but it takes with it the original picturebox which I drag it doesn't
leave it on its place.
So you want to make a copy when the PictureBox is dropped?
In the MouseDown() handler, store the original location in the Tag() property:
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
p = (PictureBox)sender;
p.Tag = p.Location; // <-- store the Location in the Tag() property
// ... rest of the existing code ...
}
}
In the MouseUp() handler, put a New PictureBox in the current location and reset the original:
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
p = (PictureBox)sender;
// create a new PictureBox that looks like the original:
PictureBox PB = new PictureBox();
PB.Size = p.Size;
PB.Image = p.Image;
PB.SizeMode = p.SizeMode;
PB.BorderStyle = p.BorderStyle;
// etc...make it look the same
// ...and place it:
Control c = GetChildAtPoint(new Point(p.Left - 1, p.Top));
if (c == null) c = this;
Point newLoc = c.PointToClient(p.Parent.PointToScreen(p.Location));
PB.Parent = c;
PB.Location = newLoc;
p.Parent.Controls.Add(PB); // <-- add new PB to the form!
// put the original back where it started:
p.Location = (Point)p.Tag;
}
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);