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 :.
Related
I want to move a car first horizontally then after some time like after 100 sec that car should be hidden and from that point a new car display and move vertically from that point.
here I am done with horizontally moving of car.
public Form1()
{
InitializeComponent();
timer1.Interval = 40;
timer1.Start();
}
int i = 0;
private void timer1_Tick(object sender, EventArgs e)
{
time_for_car1_to_B();
}
public void time_for_car1_to_B()
{
i++;
pictureBox1.Left += 2;
label1.Text = i + "sec";
if (i == 100)
{
timer1.Stop();
pictureBox1.Hide();
}
}
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();
I'm sending to my method different images and I want insert some effect to this change.
How can I fade in and fade out images?
private void ShowImage(Image image, ImageLayout imageLayout, int numberOfSeconds)
{
try
{
if (this.image_timer != null)
this.KillImageTimer();
this.customer_form.DisplayImage(image, imageLayout);
this.image_timer = new Timer();
this.image_timer.Tick += (object s, EventArgs a) => NextImage();
this.image_timer.Interval = numberOfSeconds* 1000;
this.image_timer.Start();
}
catch
{
//Do nothing
}
public void DisplayImage(Image image, ImageLayout imageLayout)
{
panel1.BackgroundImage = image;
panel1.BackgroundImageLayout = imageLayout;
}
There are no built-in fading transitions in Winforms.
So you will need to write one yourself.
The simplest one I can think of uses a second Panel, that is layered upon the first one and in fact needs to be inside the first Panel or else the transparency effect won't work..
Here is the setup, using two Panels:
public Form1()
{
InitializeComponent();
pan_image.BackgroundImage = someImage;
pan_layer.Parent = pan_image;
pan_layer.BackColor = pan_image.BackColor;
pan_layer.Size = pan_image.Size;
pan_layer.Location = Point.Empty;
}
For the fading animation I use a Timer. This is a quick code example:
Timer timer1 = new Timer();
int counter = 0;
int dir = 1; // direction 1 = fade-in..
int secondsToWait = 5;
int speed1 = 25; // tick speed ms
int speed2 = 4; // alpha (0-255) change speed
void timer1_Tick(object sender, EventArgs e)
{
// we have just waited and now we fade-out:
if (dir == 0)
{
timer1.Stop();
dir = -speed2;
counter = 254;
timer1.Interval = speed2;
timer1.Start();
}
// the next alpha value:
int alpha = Math.Min(Math.Max(0, counter+= dir), 255);
button1.Text = dir > 0 ? "Fade In" : "Fade Out";
// fully faded-in: set up the long wait:
if (counter >= 255)
{
timer1.Stop();
button1.Text = "Wait";
timer1.Interval = secondsToWait * 1000;
dir = 0;
timer1.Start();
}
// fully faded-out: try to load a new image and set direction to fade-in or stop
else if (counter <= 0)
{
if ( !changeImage() )
{
timer1.Stop();
button1.Text = "Done";
}
dir = speed2;
}
// create the new, semi-transparent color:
Color col = Color.FromArgb(255 - alpha, pan_image.BackColor);
// display the layer:
pan_layer.BackColor = col;
pan_layer.Refresh();
}
I start it in a Button, on which I also show the current state:
private void button1_Click(object sender, EventArgs e)
{
dir = speed2;
timer1.Tick += timer1_Tick;
timer1.Interval = speed1;
timer1.Start();
}
As you can see I use two speeds you can set: One to control the speed of the Timer and one to control the steps by which the transparency changes on each Tick.
The effect is created by simply changing the Color from the BackgroundColor of the image Panel to fully transparent and back, waiting in between for a specified number of seconds.
And the end of the effect I call a function changeImage() to change the images. If this function returns false the Timer is stopped for good..
I'm pretty sure this could be written in a cleaner and more elegant way, but as it is it seems to work..
Update
for flicker-free display use a double-buffered control, like this Panel subclass:
class DrawPanel : Panel
{
public DrawPanel() { DoubleBuffered = true; }
}
Here is a sample implementation for changeImage:
bool changeImage()
{
if (pan_image.BackgroundImage != null)
{
var img = pan_image.BackgroundImage;
pan_image.BackgroundImage = null;
img.Dispose();
}
pan_image.BackgroundImage = Image.FromFile(imageFiles[index++]);
return index < imageFiles.Count;
}
It assumes two class level variables: a List<string> imageFiles filled with file names of images for a slide-show and an int index = 0.
I am looking for an efficient way of scrolling text like a marquee in web terminology.
I managed to achieve this using a piece of code I found online:
private int xPos = 0, YPos = 0;
private void Form1_Load(object sender, EventArgs e)
{
//link label
lblText.Text = "Hello this is marquee text";
xPos = lblText.Location.X;
YPos = lblText.Location.Y;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (xPos == 0)
{
this.lblText.Location = new System.Drawing.Point(this.Width, YPos);
xPos = this.Width;
}
else
{
this.lblText.Location = new System.Drawing.Point(xPos, YPos);
xPos -= 2;
}
}
The code is very simple and it uses, a timer tick event.
It works great initially, but after scrolling 3 or 4 times, it does not reappear.
Is there anything I can adjust to make the scrolling infinite?
try:
private void timer1_Tick(object sender, EventArgs e)
{
if (xPos <= 0) xPos = this.Width;
this.lblText.Location = new System.Drawing.Point(xPos, YPos);
xPos -= 2;
}
You mentioned that it 'cuts off' if the string is longer than the form width. I assume you mean that the label jumps back to the right side of the form as soon as it hits the left side, which means you can't read the full text?
If so, you could set the 'minimum Left' of the Label to be the negative of it's width. This would allow the label to scroll fully off the form before resetting it:
private void timer1_Tick(object sender, EventArgs e)
{
// Let the label scroll all the way off the form
int minLeft = this.lblText.Width * -1;
if (xPos <= minLeft) xPos = this.Width;
this.lblText.Location = new Point(xPos, yPos);
xPos -= 2;
}
Or, you can set the 'minimum Left' to be the negative of the difference between the label width and the form width, so that it would not reset until the rightmost characters have been shown:
private void timer1_Tick(object sender, EventArgs e)
{
// Ensure that the label doesn't reset until you can read the whole thing:
int minLeft = (lblText.Width > this.Width) ? this.Width - lblText.Width : 0;
if (xPos <= minLeft) xPos = this.Width;
this.lblText.Location = new Point(xPos, yPos);
xPos -= 2;
}
Many other options, too. Like having multiple labels running back to back in rotation, so there is never any blank text!! You can figure out how many labels to generate dynamically (based on the difference between their width and the form's width) and handle their positions in the Timer event.
If you fill the Label by adding blanks til it has the length you want, this may look nicer:
private void timer1_Tick(object sender, EventArgs e)
{
lblText.Text=
lblText.Text.Substring(1) + lblText.Text.Substring(0,1);
}
Adding the right amount of blanks may be a bit of a challenge, though. You will need to do that on Form.Resize! Doing this right is a bit trickier, than one might think.
The perfect marquee would combine the pixelwise movement and the rollover effect, maybe by owner-drawing the label, maybe like this 'Real Marquee', so 80s ;-)
class Marquee : Label
{
public Timer MarqueeTimer { get; set; }
public int Speed { get; set; }
public int yOffset { get; set; }
public void Start() { MarqueeTimer.Start(); }
public void Stop() { MarqueeTimer.Stop(); }
private int offset;
SolidBrush backBrush ;
SolidBrush textBrush ;
public Marquee()
{
textBrush = new SolidBrush(this.ForeColor);
backBrush = new SolidBrush(this.BackColor);
yOffset = 0;
Speed = 1;
MarqueeTimer = new Timer();
MarqueeTimer.Interval = 25;
MarqueeTimer.Enabled = true;
MarqueeTimer.Tick += (aSender, eArgs) =>
{
offset = (offset - Speed);
if (offset < -this.ClientSize.Width) offset = 0;
this.Invalidate();
};
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.FillRectangle(backBrush, e.ClipRectangle);
e.Graphics.DrawString(this.Text, this.Font, textBrush, offset, yOffset);
e.Graphics.DrawString(this.Text, this.Font, textBrush,
this.ClientSize.Width + offset, yOffset);
}
}
Looks really smooth and needs no outside code but Start, Stop and setting Speed and perhaps the MarqueeTimer Intervall. All regular Properties will work from the Designer, just set AutoSize=false and make it large enough to fill the area!
I have a Button in my form and a PictureBox with width 290 and height 145 that is hidden at first . I want to show the PictureBox little by little while the button's MouseEnter event happens . So I tried this code :
private void button1_MouseEnter(object sender, EventArgs e)
{
pictureBox1.Size = new Size(0, 145);
pictureBox1.Show();
for (int i = 0; i < 290; i++)
pictureBox1.Size = new Size(i, 145);
}
But it shows the PictureBox immediately with the primary size .
I found a similar question in this site ( PictureBox does not change its size ) , but actually its answers couldn't help me , too .
Your code executes all at once, so all you will see is a sudden change.
Use a timer and gradually increase the size when the timer ticks.
timer = new Timer(16); //~60 FPS
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
...
private void button1_MouseEnter(object sender, EventArgs e)
{
pictureBox1.Size = new Size(0, 145);
pictureBox1.Show();
timer.Enabled = true; // Enable it
}
...
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (pictureBox1.Width < 290)
pictureBox1.Width++; //Increment
else
timer.Enabled = false; //Disable
}
You must use the Update method of your pictureBox in order to redraw it. Also a little delay will change the size more smoothly on Faster computers.
I changed your code like this:
private void button1_MouseEnter(object sender, EventArgs e)
{
pictureBox1.Size = new Size(145, 145);
for (int i = 145; i < 290; i++)
{
pictureBox1.Size = new Size(i, i);
pictureBox1.Update();
System.Threading.Thread.Sleep(1);
}
}
1) define a new int as public :
public partial class Form1 : Form
{
int counter = 0;
.
.
.
2) use a timer :
private void timer1_Tick(object sender, EventArgs e)
{
counter = counter + 10;
timer1.Interval = 10;
pictureBox1.Show();
if (counter <= 290)
{ pictureBox1.Width += 1; }
}
3) enable the timer in mouse event:
private void button1_MouseEnter(object sender, EventArgs e)
{
counter = 0;
pictureBox1.Width = 0;
timer1.Enabled = true;
}