I've been searching about this for a while and haven't found what I'm looking for.
I want to be able to have an image in a picturebox that can be positioned to a point by means of a "search box". Basically, mapping locations in pixels to certain phrases or letters that then shift the position on the picturebox.
I tried to set the location using points, however this does not change the picture at all; the location after calculating the code below stubbornly stays at (3,3).
The picture also is large (~3500 x ~3000) and needs scrolls bars to fully view it.
Here's my code
public Form1()
{
InitializeComponent();
flowLayoutPanel1.AutoScroll = true;
pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
flowLayoutPanel1.Controls.Add(pictureBox1);
}
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text == "m")
{
pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
pictureBox1.Image = Image.FromFile(#"C:\User\Desktop\map.jpg");
pictureBox1.Location = new Point(700, 200);
// ^ The location does not change and stays at (3,3)
// The picturebox is not set as locked
}
Do I need to do something different? Or is the issue with my picture for not allowing me to change the location?
EDIT I found the Solution thanks to the help below. I had to use a panel and place the picturebox within. Below is the code I used.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
panel1.AutoScroll = true;
panel1.Controls.Add(pictureBox1);
pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
pictureBox1.Image = Image.FromFile(#"C:\Desktop\image.jpg");
}
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.Visible = true;
label1.Visible = true;
int Hvalue = panel1.HorizontalScroll.Value;
label1.Text = Hvalue.ToString();
label2.Visible = true;
int Vvalue = panel1.VerticalScroll.Value;
label2.Text = Vvalue.ToString();
if (textBox1.Text == "m")
{
// these are just values that I put in
panel1.HorizontalScroll.Value = 616;
panel1.VerticalScroll.Value = 90;
}
}
Related
public Form1()
{
InitializeComponent();
this.imgRoom.Click += new EventHandler(this.pictureBox1_Click);
}
private void pictureBox1_Click(object sender, EventArgs e)
{
var label1 = new LabelControl();
label1.Location = MousePosition;
label1.BackColor = Color.Red;
label1.Parent = imgRoom;
label1.Text = "Point";
imgRoom.Controls.Add(label1);
}
When I click in place, which you can see on the attached screen, point appear in another place. How to solve this problem?
MousePosition is in screen coordinates. You need to convert it to client coordinates.
private void pictureBox1_Click(object sender, EventArgs e)
{
var label1 = new LabelControl();
label1.Location = imgRoom.PointToClient(MousePosition); // changed here.
label1.BackColor = Color.Red;
label1.Parent = imgRoom;
label1.Text = "Point";
imgRoom.Controls.Add(label1);
}
Looks like you have to the mouse position relative to the form not the picture box. Try using the pictureBox 'mouseClick' event and then using the mouseEventArgs 'e.Location' property to set your label's Location property.
see - (https://msdn.microsoft.com/en-us/library/system.windows.forms.control.mouseclick(v=vs.110).aspx)
I have tried using Tag, Name, Text, IndexOf. Every time, I get the first name and that's it. Here is the code:
// Perform scanning
for (;;)
{
List<System.Drawing.Image> images = this.ScannerDevice.PerformScan().ToList();
// Show picture in window
this.Invoke((MethodInvoker)delegate
{
this.FrontImage = images[0];
foreach (System.Drawing.Image image in images)
{
PictureBox pf = new PictureBox();
pf.SizeMode = PictureBoxSizeMode.StretchImage; pf.Height = 150; pf.Width = 170;
pf.Image = image;
pf.Click += new EventHandler(pictureClicked);
flowLayoutPanel1.Controls.Add(pf);
pf.Tag=flowLayoutPanel1.Controls.Count;
}
ScanFinishedEventArgs eventArgs = new ScanFinishedEventArgs { AcceptScan = true };
this.ScanFinished?.Invoke(this, eventArgs);
label1.Text = Convert.ToString(flowLayoutPanel1.Controls.Count);
});
}
void pictureClicked(object sender, EventArgs e)
{
if (selectedPicture != null)
selectedPicture.BorderStyle = BorderStyle.None;
selectedPicture = (PictureBox)sender;
selectedPicture.BorderStyle = BorderStyle.FixedSingle;
pictureBox1.Image = selectedPicture.Image;
label2.Text = Convert.ToString(pf.Tag);
}
Also I would like to use that name later to be displayed in another label when I click on the certain picturebox.
Also I have tried using anonymous types but unable to use it with image objects. What am I doing wrong?
I've just done this and it seems to work. 3 images are added, each named according to the index value at the time. A label is set showing the image count. The picture clicked handler displays the name in a message box when the image is clicked.
private void button1_Click(object sender, EventArgs e)
{
int index = 0;
foreach (Image image in images.Images)
{
PictureBox pf = new PictureBox();
pf.SizeMode = PictureBoxSizeMode.StretchImage;
pf.Height = 50;
pf.Width = 50;
pf.Click += new EventHandler(PictureClicked);
pf.Name = index.ToString();
pf.Image = image;
flowLayoutPanel1.Controls.Add(pf);
index++;
}
lblImagecount.Text = index.ToString();
}
private void PictureClicked(object sender, EventArgs e)
{
MessageBox.Show(((PictureBox) sender).Name);
}
I'm trying to do transparent and clickable form. This form will work full screen. So this form must be clickable. For example if desktop exists behind this form, I must be able to click to folders and open.
If a document exists I must be able to change this document. I couldn't solve how to enable this.
I think it can be done with API codes, but I don't know which API. If you can give me some information/link I will be pleased.
This is simple and works without calling any API function.
But it will prohibit any interaction of your program with the user..
For a Screensaver this makes no sense, however, at least not as you described it.
The rule is this:
Anything that is not 100% transparent is not click-through.
So you could easily create a darker screen using Opacity and a Black BackColor but it won't be click-through.
The simplest solution would be to switch between the both modes upon MouseMove using a Timer to turn the saving mode back on, maybe like this:
public Form1()
{
InitializeComponent();
this.Text = "";
this.MinimizeBox = false;
this.MaximizeBox = false;
this.ControlBox = false;
this.WindowState = FormWindowState.Maximized;
switchSaverState(false);
}
Point lastMosePosition = Point.Empty;
int savingWaitMinutes = 10;
int minute = 60000;
Timer timer1 = new Timer;
void switchSaverState(bool saving)
{
if (saving)
{
this.BackColor = Color.Black;
this.Opacity = 0.8;
}
else
{
this.TransparencyKey = Color.Fuchsia;
this.BackColor = Color.Fuchsia;
this.Opacity = 1;
timer1.Interval = minute * savingWaitMinutes;
timer1.Start();
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (timer1.Interval == minute * savingWaitMinutes)
{
timer1.Interval = 100;
switchSaverState(true);
lastMosePosition = Cursor.Position;
}
else
{
if (Cursor.Position != lastMosePosition) { switchSaverState(false); }
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
lastMosePosition = Cursor.Position;
switchSaverState(false);
}
But again: This is like a Screensver, meaning that you can't work while it 'saves'! To do that use the controls on your monitor!!
First of all I am a beginner with C#.
I have a picturebox and a timer (enabled, interval = 25).
I have inserted a gif image of a bird in the picturebox.
And in the Timer event I have written,
bool positionBird = true;
private void timer1_Tick(object sender, EventArgs e)
{
if (PictureBox1.Location.X == Screen.PrimaryScreen.Bounds.Width)
{
positionBird = false;
}
else if (PictureBox1.Location.X == 0)
{
positionBird = true;
}
if(positionBird)
{
PictureBox1.Left += 1;
}
else
{
PictureBox1.Left += -1;
}
}
But what I want to achieve is, when the picture box touches the right
boundary and condition become false, I want to flip the image of bird in
the picturebox. Right now the bird is doing Michael Jackson's Moonwalk!
I tried to flip the bird (mirror the bird) using the below code.
else
{
PictureBox pict = new PictureBox();
pict = PictureBox1;
pict.Image.RotateFlip(RotateFlipType.RotateNoneFlipX);
pict.Left += -1;
}
But it looks weird. It shows the flip image and normal image both. Can
someone help me on this? As I already said I am a beginner. Some simple
code with explanation would be very helpful. Also can someone tell me
what I am doing wrong?
DO NOT CREATE another Picture Box. You are seeing the original picture because you have not modified the original but the newly created one.
So the modified code is follows:
bool positionBird = true;
private void timer1_Tick(object sender, EventArgs e)
{
if (PictureBox1.Location.X == Screen.PrimaryScreen.Bounds.Width)
{
positionBird = false;
PictureBox1.Image.RotateFlip(RotateFlipType.RotateNoneFlipX); // picture flips only once when touches boundary
}
else if (PictureBox1.Location.X == 0)
{
positionBird = true;
PictureBox1.Image.RotateFlip(RotateFlipType.RotateNoneFlipX); // picture flips only once when touches boundary
}
if(positionBird)
{
PictureBox1.Left += 1;
}
else
{
PictureBox1.Left += -1;
}
}
This is the Play button code:
private void btnPlay_Click(object sender, EventArgs e)
{
_files = new List<FileInfo>();
_indx = 0;
DirectoryInfo dir = new DirectoryInfo(filesForanimation);
if (_files == null)
_files = new List<FileInfo>();
fi1 = dir.GetFiles("*.bmp");
_files.AddRange(fi1);
_files = _files.OrderBy(f => f.LastWriteTime).ToList();
button14.ForeColor = Color.Red;
button13.ForeColor = Color.Black;
button12.ForeColor = Color.Black;
timer3.Start();
button13.Enabled = true;
button13.Text = "Pause";
button12.Enabled = true;
trackBar1.Maximum = fi1.Length;
trackBar1.Minimum = 0;
}
Then the timer tick event:
private void timer3_Tick(object sender, EventArgs e)
{
try
{
Image iOLd = this.pictureBox1.Image;
trackBar1.Value = _indx;
label23.Text = _files[_indx].Name;
if (checkBox1.Checked)
{
Image img = Image.FromFile(_files[_indx].FullName);
this.pictureBox1.Image = img;
this.pictureBox1.Image = null;
pictureBox1.Refresh();
}
else
{
Image img = Image.FromFile(_files[_indx].FullName);
this.pictureBox1.Image = img;
}
if (iOLd != null)
// iOLd.Dispose();
_indx++;
if (_indx >= _files.Count)
{
_indx = 0;
trackBar1.Value = 0;
}
timer3.Interval = Convert.ToInt32(numericUpDown1.Value);
}
catch
{
}
}
And the checkBox check event:
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
Graphics g = Graphics.FromImage(pictureBox1.Image);
g.Clear(SystemColors.Control);
pictureBox1.Invalidate();
}
else
{
pictureBox1.Load(fi[trackBar1.Value].FullName);
pictureBox1.Invalidate();
}
}
The problem is in the timer tick. First time i tried inside the if (checkBox1.Checked) i did only pictureBox1.Refresh(); but then when hitting play button its showing big red X with white background. So i marked // the line: iOLd.Dispose(); so now i see the drawings the pixels only but they never change i guess for some reason it dosent load the new image from the hard disk as it suppose to do so its keep moving over and over the same image.
So i tried in the if (checkBox1.Checked)
to do as it is now:
Image img = Image.FromFile(_files[_indx].FullName);
this.pictureBox1.Image = img;
this.pictureBox1.Image = null;
pictureBox1.Refresh();
But in this case the trackBar and the timer moving once to image number 2 and stop there without doing anything.
And this happennig only when the checkBox is checked if its not checked and in the pictureBox there are the pixels and the background image its working fine.
** I modified cleared and made the question shorter **
You should not draw onto a graphics object from a non-persisted method such as a check change event.
You should handle the Paint event of the PictureBox so that your graphics are redrawn each time the PictureBox needs to refresh (such as when changing the background image). As it stands you will most likely lose your graphics if you move the window around enough too.
For example:
pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
// draw your pixels here
}
NOTE: Picture boxes have there uses and there problems, if you want to do custom drawing I would recommend just drawing onto a standard panel instead.