I am working on a image viewer and have encountered a small problem.
I load the images into the program using a dialog box then put them into individual picture boxes.
I do not know how to do the onclick for each picture box as when its clicked I want that image to display in a bigger picture box.
public partial class Form1 : Form
{
List<Bitmap> images = new List<Bitmap>();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int x = 0;
openFileDialog1.Filter = "Image Files(*.jpg; *.jpeg; *.bmp)|*.jpg; *.jpeg; *.bmp";
openFileDialog1.Multiselect = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
foreach(String fileName in openFileDialog1.FileNames)
{
images.Add(new Bitmap(fileName));
PictureBox pb = new PictureBox();
Image loadedImage = Image.FromFile(fileName);
pb.SizeMode = PictureBoxSizeMode.StretchImage;
pb.Width = flowLayoutPanel1.Width;
pb.Height = 200;
pb.Image = loadedImage;
pb.MouseClick += pb_MouseClick;
flowLayoutPanel1.Controls.Add(pb);
pb.Name = "" + x;
x++;
}
}
MessageBox.Show(String.Format("{0} images loaded",images.Count),"",MessageBoxButtons.OK);
}
private void Form1_Load(object sender, EventArgs e)
{
}
void pb_MouseClick(object sender, MouseEventArgs e)
{
// handle click event
if (e.Button == MouseButtons.Left)
MessageBox.Show("Image clicked");
pbMain.Image = images[0];
pbMain.SizeMode = PictureBoxSizeMode.StretchImage;
}
}
If, in your Click handler for the picture boxes, cast sender to a PictureBox like so:
PictureBox pb = (PictureBox)sender;
Then you don't need to know which one specifically was clicked. Just use that reference to grab the image and put it in the larger box.
Related
I am trying to create a Form in Visual Studio Windows Forms Apps C# in which during runtime the user or operator can create a new picturebox with a left mouse click and then have the ability to move each picturebox created.
I really do not know where to begin. Anyone have any ideas?
To add a new PictureBox dynamically, you can subscribe to the event Form_MouseClick and create the PictureBox like this:
public Form1()
{
InitializeComponent();
this.MouseClick += Form_MouseClick;
}
private void Form_MouseClick(object sender, MouseEventArgs e)
{
PictureBox pictureBox = new PictureBox();
// cursor location
pictureBox.Location = new Point(e.X, e.Y);
pictureBox.BackColor = Color.Red;
this.Controls.Add(pictureBox);
}
To drag and move the PictureBox, you also nee to subscribe to the event MouseDown, MouseUp, and MouseMove.
Here is a simple demo you can refer to.
private void Form_MouseClick(object sender, MouseEventArgs e)
{
// create new control
PictureBox pictureBox = new PictureBox();
pictureBox.Location = new Point(e.X, e.Y);
pictureBox.BackColor = Color.Red;
this.Controls.Add(pictureBox);
// bind event for each PictureBox
pictureBox.MouseDown += pictureBox_MouseDown;
pictureBox.MouseUp += pictureBox_MouseUp;
pictureBox.MouseMove += pictureBox_MouseMove;
}
Point mouseDownPoint = Point.Empty;
Rectangle rect = Rectangle.Empty;
bool isDrag = false;
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mouseDownPoint = e.Location;
rect = (sender as PictureBox).Bounds;
}
}
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (isDrag)
{
isDrag = false;
(sender as PictureBox).Location = rect.Location;
this.Refresh();
}
reset();
}
}
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDrag = true;
rect.Location = this.PointToClient((sender as PictureBox).PointToScreen(new Point(e.Location.X - mouseDownPoint.X, e.Location.Y - mouseDownPoint.Y)));
this.Refresh();
}
}
private void reset()
{
mouseDownPoint = Point.Empty;
rect = Rectangle.Empty;
isDrag = false;
}
You can add the form elements during runtime:
var picture = new PictureBox
{
Name = "pictureBox",
Size = new Size(16, 16),
Location = new Point(100, 100),
Image = Image.FromFile("test.jpg"),
};
this.Controls.Add(picture);
Afterward, you can move it with the Mouse Events
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 have a C# window form for importing and displaying multiple images.
I am able to import multiple images and display the first image, but got some problems on displaying images one by one.
The program flow: user click the button, then select multiple images. After that, the first image should be displayed on the picture box. When the user click the "next image button", the next image should be shown.
The first image is able to display on the picturebox but no idea on displaying them one by one.
Is there any configuration for achieving this or how to implement it through coding.
Thanks everyone.
My coding:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
InitializeOpenFileDialog();
}
private void InitializeOpenFileDialog()
{
// Set the file dialog to filter for graphics files.
this.openFileDialog1.Filter =
"Images (*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|" +
"All files (*.*)|*.*";
// Allow the user to select multiple images.
this.openFileDialog1.Multiselect = true;
this.openFileDialog1.Title = "My Image Browser";
}
private void SelectFileButton_Click(object sender, EventArgs e)
{
DialogResult dr = this.openFileDialog1.ShowDialog();
if (dr == System.Windows.Forms.DialogResult.OK)
{
// Read the files
foreach (String file in openFileDialog1.FileNames)
{
// Create a PictureBox.
PictureBox pb = new PictureBox();
Image loadedImage = Image.FromFile(file);
pb.Height = loadedImage.Height;
pb.Width = loadedImage.Width;
pb.Image = loadedImage;
flowLayoutPanel1.Controls.Add(pb);
}
}
}
}
IMHO, there is a better way for achieving that.
You don't have to add PictureBox control for each image, it will overload your form.
My suggestion is to keep a list of all loaded images, and an indexer of the current shown image.
Code:
Add a PictureBox to your form (let's call it pictureBox1), where you want the images to shown.
In addition, add these properties to your class:
private List<Image> loadedImages = new List<Image>();
private int currentImageIndex;
In your "load images" button click event:
private void SelectFileButton_Click(object sender, EventArgs e)
{
DialogResult dr = this.openFileDialog1.ShowDialog();
if (dr == System.Windows.Forms.DialogResult.OK)
{
loadedImages.Clear();
// Read the files
foreach (String file in openFileDialog1.FileNames)
{
// Create a PictureBox.
loadedImages.Add(Image.FromFile(file));
}
if (loadedImages.Count > 0)
{
currentImageIndex = 0;
pictureBox1.Image= loadedImages[currentImageIndex];
}
}
}
And finally, for Next/Previous buttons click event you can add this code:
// Mod function to support negative values (for the back button).
int mod(int a, int b)
{
return (a % b + b) % b;
}
// Show the next picture in the PictureBox.
private void button_next_Click(object sender, EventArgs e)
{
currentImageIndex = mod(currentImageIndex + 1, loadedImages.Count);
pictureBox1.Image = loadedImages[currentImageIndex];
}
// Show the previous picture in the PictureBox.
private void button_prev_Click(object sender, EventArgs e)
{
currentImageIndex = mod(currentImageIndex - 1, loadedImages.Count);
pictureBox1.Image = loadedImages[currentImageIndex];
}
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
I have a pictureBox with an image inside.
I want, when i click on a button the image should hide and click again to show the image.
In the pictureBox, using paint event i am drawing some lines.
So if im doing pictureBox1.Refresh(); it will draw the lines. I want that if i click on a button the image will not display on/off.
pictureBox1 = null; or pictureBox1.Image.Dispose(); doesn't work it's showing me big red x with white background.
To hide it:
pictureBox.Visible = false;
To hide/show it in a click event:
void SomeButton_Click(Object sender, EventArgs e)
{
pictureBox.Visible = !pictureBox.Visible;
}
For toggling the image in your PictureBox you can create a 1 pixel bitmap and assign it to the picture box when you want hide your image, then assign your image back again. I am a little unclear of what the second part of your question is asking, any drawing in the picturebox's Paint Event will remain unless you exclude it in the Paint Event based on some Condition. If you want to draw a line in the box an toggle it on/off from a button see my second example.
i.e.
public partial class Form1 : Form
{
Bitmap nullBitmap = new Bitmap(1, 1); // create a 1 pixel bitmap
Bitmap myImage = new Bitmap("Load your Image Here"); // Load your image
bool showImage; // boolean variable so we know what image is assigned
public Form1()
{
InitializeComponent();
pictureBox1.Image = myImage;
showImage = true;
}
private void button1_Click(object sender, EventArgs e)
{
if (showImage)
{
pictureBox1.Image = nullBitmap;
showImage = false;
}
else
{
pictureBox1.Image = myImage;
showImage = true;
}
}
}
Second Example
public partial class Form1 : Form
{
bool showLines;
public Form1()
{
InitializeComponent();
showLines = true;
}
private void button1_Click(object sender, EventArgs e)
{
if (showLines)
{
showLines = false;
pictureBox1.Invalidate();
}
else
{
showLines = true;
pictureBox1.Invalidate();
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if(showLines)
e.Graphics.DrawLine(Pens.Purple, 0, 0, 100, 100);
}
}
picturebox1.BackgroundImage = null