Hi guys I have searched for an answer but I have not found a particular answer that would help me. So I am asking this question.
My question is how do you detect if your picturebox moves outside the window or form.
Each tick of my timer does:
picturebox.Left += 10;
if (picturebox.Left > this.Width)
{
picturebox.Left = 0;
}
But this code only goes to the right side and only detects if the picturebox went out on the right side of the form.
I have tried doing something like lets say I'm moving the picturebox to the left and it went out of the screen, this is the code I have got and this doesnt give any error but it will move my image so fast then.
picturebox.Left -= 10;
if (picturebox.Left > this.width || picturebox.Left < this.Width)
{
picturebox.Left = 0;
}
This piece of code doesnt work for me either:
picturebox.Right < this.Width
Please help,
Thanks
Here's one way...
private int direction = -1;
private void button1_Click(object sender, EventArgs e)
{
direction = direction * -1;
}
private void timer1_Tick(object sender, EventArgs e)
{
picturebox.Left += direction * 10;
if (!this.ClientRectangle.IntersectsWith(picturebox.Bounds))
{
if (direction == -1)
picturebox.Left = this.ClientRectangle.Width;
else
picturebox.Left = -picturebox.Width;
}
}
Try this.
private bool IsControlInsideClientArea(Control c)
{
return this.ClientRectangle.Contains(this.RectangleToClient(c.RectangleToScreen(c.ClientRectangle)));
}
Related
I have a class assignment to move a picturebox randomly across the form. Once you click on the picturebox, it is supposed to scream and change the picture then change it back to the original picture. When you click again, it is supposed to go faster. I have it working up to the point of making it go faster. Here is my code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
tm1.Interval = 1000;
tm1.Tick += new EventHandler(tm_Tick);
}
Timer tm1 = new Timer();
int X = 0;
int Y = 0;
private void pictureBox1_Click(object sender, EventArgs e)
{
if (timer1.Enabled)
{
timer1.Stop();
pictureBox1.Image = Properties.Resources.Mimikyu;
Application.DoEvents();
pictureBox1.WaitOnLoad = true;
System.Threading.Thread.Sleep(10);
SoundPlayer sp = new SoundPlayer(Properties.Resources.screa);
sp.PlaySync();
pictureBox1.Image = Properties.Resources.Evee;
}
else
timer1.Start();
}
private void tm_Tick(object sender, EventArgs e)
{
int X = ((int)(new Random().Next(0, 1000)));
int Y = ((int)(new Random().Next(0, 500)));
if (X > 1025 - pictureBox1.Width)
{
X = 1025 - pictureBox1.Width;
}
if (Y > 545 - pictureBox1.Height)
{
Y = 545 - pictureBox1.Height;
}
pictureBox1.Location = new Point(X, Y);
}
}
}
Point me to where I need to go to get the interval to move faster and faster after each click Thank you.
decreasing the tm1.Interval should do it
...
else
if (tm1.Interval>10){tm1.Interval -= 10;}
timer1.Start();
Here is my key code:
using System;
using System.Windows.Forms;
namespace Scroller
{
public partial class Form1 : Form
{
int i, j;
bool k = false;
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
label1.Text = "Time:"+ System.DateTime.Now.ToString();
i--;
j = i + this.Width;
if (i < this.Width && i > 0)
{
label1.Left = i;
}
else
if (i < 0 && k == false)
{
label1.Left = i;
k = true;
}
else
if (i < 0 && k == true)
{
label1.Left = j;
k = false;
}
if (i < 0 - label1.Width)
{
i = this.Width - label1.Width;
}
}
private void Form1_Load(object sender, EventArgs e)
{
label1.Text = "Time:"+ System.DateTime.Now.ToString();
i = this.Width - label1.Width;
label1.Left = i;
}
}
}
The effect that I want to make is the whole time string move right to left. When a pixel of the text disappear on the left side (because it is out of the form's left border),the pixel will shows on the right side.
In other words, the effect can't be make by delete the first character of string and append it to the last.
I knew that it will be easier to use two label to do it. Set one's location in the form and hide the other right by the form. Move them in the same time.
When the first label hit the left border of the form, the second hit the right border of the form. And the first one move out, the second move in. Until the second totally move in, reset their x location.
But I just want to use one label. So I chose to quickly switch the label's location, and try to "cheat" user's eye. The problem is when the label switch between left and right, it flash very obviously. Even though I set timer's interval below 20,the problem still exist.
Could you help me dissolve the flash problem or enlighten me other ways which can just use one label and one timer to make the effect I need?
Thanks. If I didn't describer my problem clear enough or need more code, please let me know.
I don't think you can work out the flashing problem changing the label's location in a windows form.
Another solution would be to set the label width the same size as the form width, make the label text fill all the width using spaces and make the timer always get the last character and put it on the beginning of the string.
Sample code below.
private void timer1_Tick(object sender, EventArgs e)
{
label1.Text = label1.Text.Substring(label1.Text.Length - 1) + label1.Text.Remove(label1.Text.Length - 1);
}
private void Form1_Load(object sender, EventArgs e)
{
// The total spaces required to fill the form vary from form.width and the initial label.text.width
// Width | Spaces
// 177 | 13
// 228 | 30
// 297 | 53
// 318 | 60
// The spacesEnd = 60 work for a form with width 319
int spacesBegin = 0, spacesEnd = 60;
label1.Text = "Time:" + System.DateTime.Now.ToString();
label1.AutoSize = false;
label1.Left = -3;
label1.Width = this.Width - 1;
label1.Height = 15;
label1.BorderStyle = BorderStyle.FixedSingle;
for (int i = 0; i < spacesBegin; i++)
label1.Text = " " + label1.Text;
for (int i = 0; i < spacesEnd; i++)
label1.Text += " ";
Timer timer = new Timer();
timer.Tick += timer1_Tick;
timer.Interval = 50;
timer.Start();
}
i have taken one Flow layout panel and placed multiple picture box inside in it. now i want when i will place my mouse at the right or left most edge of the Flow layout panel then rest of picture will scroll out. just think about windows 8 start screen where many tiles appear in screen and when we place mouse at right most edge on the screen then rest of the tiles scroll out. i want to simulate same thing in windows form with Flow layout panel.
i want my Flow layout panel will not show scroll bar but images will scroll out when i will place mouse right or left most part on the panel. here is my screen shot
some one told me to do it this way...here is bit code
Set AutoScrollPosition property in MouseMove event of Panel.
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
panel1.AutoScrollPosition = new Point(e.X, e.Y);
}
but this trick was not good. AutoScrollPosition works when scroll bar is visible but in my case i do not want to show scroll bar with Flow layout panel. i want smooth scrolling images from left to right or right to left. anyone can help me to achieve what i am trying to do....if possible guide me with respect of coding. thanks
EDIT
Here i am giving my full code after modification following #Taw suggestion but it is not working fine....rather flickering found when picture move. anyway here is the full code.
namespace ScrollTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
flowLayoutPanel1.MouseMove += MouseScroll;
foreach (Control x in this.Controls)
{
if (x is PictureBox)
{
((PictureBox)x).MouseMove += MouseScroll;
}
}
}
int near = 33;
private void MouseScroll(object sender, MouseEventArgs e)
{
Point mouse = flowLayoutPanel1.PointToClient(MousePosition);
Rectangle C = flowLayoutPanel1.ClientRectangle;
int dLeft = mouse.X - C.Left;
int dTop = mouse.Y - C.Top;
int dRight = C.Right - mouse.X;
int dBottom = C.Bottom - mouse.Y;
int dX = dLeft < near ? dLeft : dRight < near ? -dRight : 0;
int dY = dTop < near ? dTop : dBottom < near ? -dBottom : 0;
if (dX != 0 | dY != 0) scrollFLP(dX, dY);
}
void scrollFLP(int deltaX, int deltaY)
{
flowLayoutPanel1.Left += getSpeedFromDistance(deltaX);
flowLayoutPanel1.Top += getSpeedFromDistance(deltaY);
System.Threading.Thread.Sleep(11);
}
int getSpeedFromDistance(int delta)
{
int sig = Math.Sign(delta);
int d = Math.Abs(delta);
if (d > near / 2) return sig;
else if (d > near / 3) return near / 10 * sig;
else if (d > near / 4) return near / 8 * sig;
else if (d > near / 5) return near / 5 * sig;
else return near * sig;
}
}
}
basically i am trying achieve something like suppose i have flow layout panel and which has many picture box inside it with many images as the screen shot but scroll bar should not show rather scroll will happen automatically when i will place my mouse at the top or bottom of the flow layout panel like carousel.
see this picture of your application
when place my mouse at the right end then it scroll and form background shown which i do not want. i want picture box will scroll & scroll upto last one not more than that.
any idea how to do it. thanks
2nd Edit
this code i added as per your suggestion
public Form1()
{
InitializeComponent();
for (int i = 0; i < 666; i++)
{
PictureBox pan = new PictureBox();
//pan.MouseMove += MouseScroll;
//pan.MouseLeave += outSideCheck;
pan.Size = new Size(75, 75);
pan.BackColor = Color.FromArgb(255, (i * 2) & 255, (i * 7) & 255, (i * 4) & 255);
flowLayoutPanel1.Controls.Add(pan);
}
//flowLayoutPanel1.MouseMove += MouseScroll;
//this.flowLayoutPanel1.MouseLeave += outSideCheck;
mouseScroller MSC = new mouseScroller();
MSC.registerControl(flowLayoutPanel1); // FLP = your FlowLayouPanel
MSC.timerSpeed = 5; // optional
MSC.nearness = 100; // optional
flowLayoutPanel1.AutoScroll = false;
}
now the apps doing wired behavior after adding new code. if i am making any mistake then guide me please. thanks
This is a two-part problem:
How to grab the event
How to scroll a FlowLayoutPanel with its scrollbars invisible.
Second first. It is not an easy task from what I found, unless you use a simple and rather common trick: Don't actually scroll it! Instead place it into a Panel and then control its position inside that Panel.
To do this you add a Panel panel1 to your Form, Dock or Anchor it as you need to and set its Autoscroll = false (!) (Which is not the way it is usually done, when you want to make, say a PictureBox scrollable. But we don't want the Panel to show it Scrollbars either.)
Set the FLP to its desired size and place it into the Panel, it obviously also has Autoscroll = false, and we're ready to tackle the other problem of setting up the event..:
First you add the MouseScroll event below to your code and then you hook every control up to it you want to work with the mouse move, namely the FLP:
flowLayoutPanel1.MouseMove += MouseScroll;
..and also each of your PictureBoxes, maybe like this
// your creation loop..
PictureBox pbox = new PictureBox();
pbox.MouseMove += MouseScroll; // <<--- hook into to the mousemove
pan.MouseLeave += outSideCheck; // <<--- hook into to the mouseleave
// .. do your stuff.. here I put some paint on to test..
pbox.BackColor = Color.FromArgb(255, 111, (i * 3) & 255, (i * 4) & 255);
flowLayoutPanel1.Controls.Add(pbox);
or however you create them..
Edit 2 I have changed my original code once more. It now includes an outside check, a check for moving towards the closest edge and a workaround for tha mousemove bug. It uses a Timer set to maybe 30ms. The speed mapping is in a function of its own.
flowLayoutPanel1.MouseMove += MouseScroll;
this.flowLayoutPanel1.MouseLeave += outSideCheck;
flowLayoutPanel1.AutoScroll = false;
int near = 33;
Point lastLocation = Point.Empty;
int dX = 0;
int dY = 0;
private void MouseScroll(object sender, MouseEventArgs e)
{
Point mouse = panel1.PointToClient(MousePosition);
Rectangle C = panel1.ClientRectangle;
// mouseMove has a bug, we need to workaround
if (mouse == lastLocation) return;
if (lastLocation == Point.Empty) { lastLocation = mouse; return; }
// distance from each edge
int dLeft = mouse.X - C.Left;
int dTop = mouse.Y - C.Top;
int dRight = C.Right - mouse.X;
int dBottom = C.Bottom - mouse.Y;
// relevant distances with sign
dX = dLeft < near ? dLeft : dRight < near ? -dRight : 0;
dY = dTop < near ? dTop : dBottom < near ? -dBottom : 0;
// we need the closest edge to check if we are moving in or out
List<int> edges = new List<int>() { dLeft, dTop, dRight, dBottom };
var closest = edges.IndexOf(edges.Min());
// if we are moving
if (dX != 0 | dY != 0)
// if moving out: go else stop going
if (!movingIn(mouse, closest)) timer1.Start(); else timer1.Stop();
// remember position
lastLocation = mouse;
}
bool movingIn(Point current, int Edge)
{
switch (Edge)
{
case 0: return current.X > lastLocation.X;
case 1: return current.Y > lastLocation.Y;
case 2: return current.X < lastLocation.X;
case 3: return current.Y < lastLocation.Y;
}
return false;
}
void scrollFLP(int deltaX, int deltaY)
{
flowLayoutPanel1.Left += getSpeedFromDistance(deltaX);
flowLayoutPanel1.Top += getSpeedFromDistance(deltaY);
Size C = panel1.ClientSize;
if (flowLayoutPanel1.Left > 1) { flowLayoutPanel1.Left = 0; timer1.Stop(); }
if (flowLayoutPanel1.Right < C.Width)
{ flowLayoutPanel1.Left = C.Width - flowLayoutPanel1.Width; timer1.Stop(); }
if (flowLayoutPanel1.Top > 1) { flowLayoutPanel1.Top = 0; timer1.Stop(); }
if (flowLayoutPanel1.Bottom < C.Height)
{ flowLayoutPanel1.Top = C.Height - flowLayoutPanel1.Height; timer1.Stop(); }
}
int getSpeedFromDistance(int delta)
{
int sig = Math.Sign(delta);
int d = Math.Abs(delta);
if (d > near / 2) return sig;
else if (d > near / 3) return 2 * sig;
else if (d > near / 4) return 4 * sig;
else if (d > near / 5) return 6 * sig;
else return 10 * sig;
}
private void timer1_Tick(object sender, EventArgs e)
{
if (insidePanel()) scrollFLP(dX, dY); else timer1.Stop();
}
bool insidePanel()
{
return panel1.ClientRectangle.Contains(panel1.PointToClient(MousePosition));
}
private void outSideCheck(object sender, EventArgs e)
{
if (!insidePanel()) {timer1.Stop(); lastLocation = Point.Empty;}
}
Of course you'll want to play with the various 'magic' numbers :-)
Stop code and direction check are now included.
As usual, key is to know precisely what you want.. I hope this gets you started on ways to achieve it!
It's been a while since this question was asked. I just encountered the problem. My scenario was a little different, but I still think it's a solution to the same problem (at worst a timer control can be used because autoscroll is not turned on).
Here is my scenario: I have one panel control (normal panel). I have an PictureBox in it that I made with zoom. I'm making rectangular selections on top of this image, and when the selections spilled out of the panel, my panel was supposed to slide in the direction I was selecting. (in my scenario, mouse is pressed)(also in my scenario, autoscroll is on). This is how I solved it without writing so much code:
I added two private variable for scroll position (Valid for the whole class scope).
private int xPos;
private int yPos;
private int speed = 5;
and I assigned them the current scroll positions when the form is loaded.
private void Form1_Load(object sender, EventArgs e)
{
//when I change the scrollbar manually or change with zoom I still
//need to add these lines to the related event
xPos = panel1.HorizontalScroll.Value;
yPos = panel1.VerticalScroll.Value;
}
and inside my picturebox's mousemove event
private void picturebox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) {
Point mouse = panel1.PointToClient(MousePosition);
if (!panel1.ClientRectangle.Contains( mouse ))
{
Rectangle CRect = panel1.ClientRectangle;
int dLeft = mouse.X - CRect.Left;
int dRight = CRect.Right - mouse.X;
int dTop = mouse.Y - CRect.Top;
int dBottom = CRect.Bottom - mouse.Y;
if(dLeft < 0 && panel1.HorizontalScroll.Value > 0)
{
xPos = -panel1.AutoScrollPosition.X - speed;
}
if (dRight < 0 && panel1.HorizontalScroll.Value < panel1.HorizontalScroll.Maximum)
{
xPos = -panel1.AutoScrollPosition.X + speed;
}
if (dTop < 0 && panel1.VerticalScroll.Value > 0)
{
yPos = -panel1.AutoScrollPosition.Y - speed;
}
if (dBottom < 0 && panel1.VerticalScroll.Value < panel1.VerticalScroll.Maximum)
{
yPos = -panel1.AutoScrollPosition.Y + speed;
}
panel1.AutoScrollPosition = new Point(xPos, yPos);
}
}
}
I have been trying to code this for a while and after a couple of weeks of searching the web for an answer I decided to ask
All I want to do is gradually resize pictureBox1 to a set limit from a variable starter value when the mouse hovers over it, the furthest I got was using a forloop which made it instantly change size. I would like it to also change height and width at the same time (pictureBox1 will be a square and i just want it to be a bigger square with a bit of smooth movement)
Also I need it to gradually change back to the original size once the mouse moves off of pictureBox1.
I have been toying about with a couple of solutions found on websites but none seem to work properly, also you might need to know that I have two forms involved in this code; Form1 and frmMenu and because of a mass amount of errors I commented out the bottom two methods.
I do not get any errors but it just doesn't work.
public partial class frmMenu : Form
{
//private int size = 100;
public Timer timer1;
public frmMenu()
{
InitializeComponent();
pictureBox1.MouseEnter += new EventHandler(pictureBox1_MouseEnter);
//pictureBox1.MouseLeave += new EventHandler(pictureBox1_MouseLeave);
}
private string frmMenu_Load
{
set
{
timer1.Interval = 1;
}
}
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
//for (int i = 140; i > size; size++)
//{
//}
{
timer1.Interval = 1;
}
timer1.Enabled = true;
if (pictureBox1.Height <= 140)
{
pictureBox1.Size = new Size(pictureBox1.Size.Width, pictureBox1.Size.Height + 1);
}
else
{
timer1.Enabled = false;
}
}
// private void pictureBox1_MouseLeave(object sender, EventArgs e)
// {
// if (size > 100)
// for (int i = size; i > 100; i--)
// {
// size = i;
// }
// pictureBox1.Height = pictureBox1.Width = size;
// }
// private void pictureBox1_Click(object sender, EventArgs e)
// {
// var Form1 = new Form1();
// Form1.Show();
// var Menu = new frmMenu();
// Menu.Close();
// }
}
This is my first time asking so sorry if I haven't given enough information ^.^
Try this code:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : Form
{
bool mouseHover;
int width;
int height;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
timer1.Interval = 25;
timer1.Tick += timer1_Tick;
width = pictureBox1.Width;
height = pictureBox1.Height;
timer1.Start();
}
void timer1_Tick(object sender, EventArgs e)
{
if (mouseHover)
{
pictureBox1.Width += (pictureBox1.Width < 100) ? 5 : 0;
pictureBox1.Height += (pictureBox1.Height < 100) ? 5 : 0;
}
else
{
pictureBox1.Width += (pictureBox1.Width > width) ? -5 : 0;
pictureBox1.Height += (pictureBox1.Height > height) ? -5 : 0;
}
}
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
mouseHover = true;
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
mouseHover = false;
}
}
}
You can adjust the interval to how you like it, but increasing at 5 pixels horizontally/vertically every 25 milliseconds is pretty smooth. You need to set the initial height and width so you can go back to that size after the mouse leaves the picture box. I use the null coalescing operator so you don't have to stop the timer. As long as the condition on the left side of the ? is true, it will evaluate to the value on the left side of the :. When the condition is false, it evaluates to the right side of the :.
i have an alert form that appears at right corner of my screen and i want to increase it's height gradually,like some anti virus alerts !
i try this code but didn't work, i guess i must use degates but i do't know how and on which evaen
private void AlertForm__Load(object sender, EventArgs e)
{
const int h = 377;
int Curr = 0;
while (Curr < h)
{
this.Height = Curr;
Curr++;
Thread.Sleep(10);
}
}
could you please help me?
You are increasing the height, but that lowers the bottom of the form not moves the top up.
You should also avoid tying up interactivity with Thread.Sleep use a timer as otis suggested.
A form which doesn't respond for at least 3.77 seconds while it "scrolls" up is just going to be irritating.
private void AlertForm__Load(object sender, EventArgs e)
{
this.myTimer.Enabled = true;
}
const int h = 377;
const int quietTop = 0;
int Curr = 0;
private void myTimer_tick()
{
this.Height = Curr;
this.Top = quietTop - Curr;
Curr++;
if (Curr >= h)
this.myTimer.Enabled = false;
}