Loading gif image visible while the execution process runs - c#

I am using window app and C#.. i have a picture which is invisible at the start of the app.. when some button is clicked, the picture box has to be shown..
i use this coding but the picture box is not visible
private void btnsearch_Click(object sender, EventArgs e)
{
if (cmbproject.Text == "---Select---")
{
MessageBox.Show("Please Select Project Name");
return;
}
else
{
pictureBox1.Visible = true;
pictureBox1.BringToFront();
pictureBox1.Show();
FillReport();
Thread.Sleep(5000);
pictureBox1.Visible = false;
}
}

Don't use Sleep - that blocks the thread, which means no windows messages get processed, and your form won't get repainted.
Instead, you could use a Timer to hide the image after 5 seconds.
Add a timer to your form, and change your code to be something like this:
pictureBox1.Visible = true;
FillReport();
timer1.Interval = 5000;
timer1.Start();
And in the timer event:
private void Timer1_Tick(object sender, EventArgs e) {
pictureBox1.Visible = false;
timer1.Stop();
}
Now your image should be visible for 5 seconds.
However, the form will still not repaint while FillReport is executing. If you need the image to be visible at that point, I suggest using a BackgroundWorker to execute FillReport so that it doesn't block the UI thread. Then you can hide the image in the RunWorkerCompleted event.

Related

When CheckBox is unchecked make it unable for specific time C#

I am working on antivirus program and on real-time protection panel I want checkbox when for example "Malware protection" checkbox is unchecked to make it not enable for like 15 minutes and after that time it is enabled again so it prevents spam.
If somebody can help me it would be great
I tried with Thread.Sleep() but it stops whole application, and I tried with timer but I think I did it wrong.
This is code for timer
private void checkBox1_CheckStateChanged(object sender, EventArgs e)
{
if (this.checkBox1.Checked)
{
this.checkBox1.Text = "On";
// these two pictureboxes are for "You are (not) protected"
// picture
picturebox1.Show();
pictureBox5.Hide();
timer1.Stop();
}
else
{
this.checkBox1.Text = "Off";
// this is the problem
timer1.Start();
this.checkBox1.Enabled = true;
pictureBox1.Hide();
pictureBox5.Show();
}
}
private void timer1_Tick(object sender, EventArgs e)
{
this.checkBox1.Enabled = false;
}
Short Answer
From the code you posted, it really only appears that you need to change the code to disable the checkbox in the CheckChanged event and enable it in the timer1_Tick event (and also Stop the timer in the Tick event).
Full Answer
Winforms has a Timer control that you can use for this. After you drop a Timer onto the designer, set the Interval property to the number of milliseconds you want to wait before enabling the checkbox (1 second is 1000 milliseconds, so 15 minutes is 15min * 60sec/min * 1000ms/sec, or 900,000 ms). Then double-click it to create the Tick event handler (or add one in your Form_Load event as I've done below).
Next, in the CheckChanged event, if the checkbox is not checked, disable the checkbox and start the timer.
Then, in the Tick event, simply enable the checkbox (remember, this event is triggered after Interval milliseconds have passed) and stop the timer.
For example:
private void Form1_Load(object sender, EventArgs e)
{
// These could also be done in through designer & property window instead
timer1.Tick += timer1_Tick; // Hook up the Tick event
timer1.Interval = (int) TimeSpan.FromMinutes(15).TotalMilliseconds; // Set the Interval
}
private void timer1_Tick(object sender, EventArgs e)
{
// When the Interval amount of time has elapsed, enable the checkbox and stop the timer
checkBox1.Enabled = true;
timer1.Stop();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (!checkBox1.Checked)
{
// When the checkbox is unchecked, disable it and start the timer
checkBox1.Enabled = false;
timer1.Start();
}
}
This can be done without using Timer explicitly. Instead use asynchronous Task.Delay, which will simplify the code and make it easy to understand actual/domain intentions.
// Create extension method for better readability
public class ControlExtensions
{
public static Task DisableForSeconds(int seconds)
{
control.Enabled = false;
await Task.Delay(seconds * 1000);
control.Enabled = true;
}
}
private void checkBox1_CheckStateChanged(object sender, EventArgs e)
{
var checkbox = (CheckBox)sender;
if (checkbox.Checked)
{
checkbox.Text = "On";
picturebox1.Show();
pictureBox5.Hide();
}
else
{
checkbox.Text = "Off";
checkbox.DisableForSeconds(15 * 60);
pictureBox1.Hide();
pictureBox5.Show();
}
}
You could diseable and enable it with task.Delay(). ContinueWith(). This creates a new thread that fires after the delay is done. You need to make it thread safe, winforms isnt thread safe on its own
You should use Timer.SynchronizationObject

C# esc key not being captured when used on a form with a timer

The application I'm working on keeps track of bowling scores during tournaments. In it, there's a data entry sheet and a scoreboard. The data entry sheet has a button on which to click to launch the scoreboard form in a different thread.
private void pict_projector_Click(object sender, EventArgs e)
{
System.Threading.Thread t = new System.Threading.Thread(new
System.Threading.ThreadStart(this.openScoreboard));
t.Start();
}
private void openScoreboard()
{
frm_scoreboard frm = new frm_scoreboard();
frm.TourID = this.TourID;
frm.NightID = night_id;
Application.Run(frm);
}
On the scoreboard form I have a timer (threaded system.Timer) that ticks every second and checks if it's been 15 seconds before switching the scoreboards TableLayoutPanel to reflect the next playing divisions scores.
private void ttmr_switch_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
cnt_ticks++;
if (cnt_ticks == 15)
{
cnt_ticks = 0;
ttmr_switch.Enabled = false;
switchBoard();
}
}
On the same form (scoreboard) there's a "maximize" button which renders the form fullscreen. To exit fullscreen, I want the user to press Esc. Here is where the problem comes in.
private void frm_scoreboard_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Escape)
{
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.WindowState = FormWindowState.Normal;
pict_fullscreen.Visible = true;
}
}
The KeyDown event never gets triggered... and I lose control of the form.
After banging my head against a wall for a while, I decided to bring this to you all. Any idea how to resolve this?
Did you set the KeyPreview option of the form to true?
more information on msdn

How to wait for a button to be clicked?

After a button is clicked in a Windows form application written in C#, how to wait for another button to be clicked? Meanwhile I am updating a datagridview dynamically by current information.
EDIT
After button1 is clicked, I want to repeatedly update a dataGridView with current information and when button2 is clicked I want to stop updating the dataGridView.
Use Timer Class.
public partial class Form1 : Form
{
System.Windows.Forms.Timer timer;
public Form1()
{
InitializeComponent();
//create it
timer = new Timer();
// set the interval, so it'll fire every 1 sec. (1000 ms)
timer.Interval = 1000;
// bind an event handler
timer.Tick += new EventHandler(timer_Tick);
//...
}
void timer_Tick(object sender, EventArgs e)
{
//do what you need
}
private void button1_Click(object sender, EventArgs e)
{
timer.Start(); //start the timer
// switch buttons
button1.Enabled = false;
button2.Enabled = true;
}
private void button2_Click(object sender, EventArgs e)
{
timer.Stop(); //stop the timer
// switch buttons back
button1.Enabled = true;
button2.Enabled = false;
}
From MSDN:
A Timer is used to raise an event at user-defined intervals. This
Windows timer is designed for a single-threaded environment where UI
threads are used to perform processing. It requires that the user code
have a UI message pump available and always operate from the same
thread, or marshal the call onto another thread.
When you use this timer, use the Tick event to perform a polling
operation or to display a splash screen for a specified period of
time. Whenever the Enabled property is set to true and the Interval
property is greater than zero, the Tick event is raised at intervals
based on the Interval property setting.
So you have button A and button B. When button A is pressed you want to wait for button B to be pressed, then do something special? Without more information the simplest way is something like this:
private void OnButtonAClicked(object sender, EventArgs e)
{
ButtonA.Enabled = false;
ButtonA.Click -= OnButtonAClicked;
ButtonB.Click += OnButtonBClicked;
ButtonB.Enabled = true;
}
private void OnButtonBClicked(object sender, EventArgs e)
{
ButtonB.Enabled = false;
ButtonB.Click -= OnButtonBClicked;
// Do something truly special here
ButtonA.Click += OnButtonAClicked;
ButtonA.Enabled = true;
}
This code will toggle(initial state; button A is enabled, button B is disabled), when button A is pressed, button B becomes enabled and processes events, etc.
Use the BackgroundWorker http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
It doesn't freeze the UI, support ProgressBar, also it can be async. At the link you will see a good example with same functional that you want (start some task by click on one button and cancel it by click on another button).

Using a mouseEnter event to scale a button

this is my first post here. First off, some background, I'm new to C# and am literally in my teething stages. I'm a chemical engineer and mostly have experience with languages like MATLAB and Mathematica, but i have always liked programming and have decided to learn C# to create some user friendly interfaces for some programs I have been using. Note that i am using windows forms and not WPF.
What i would like to do is have a main menu screen linking to various forms. Now to make it look nicer, what i want to do is this; when i hover over a picturebox(the picture is of a button) in the main window i would like for the button to 'grow' a little bit, and then when i leave it should 'shrink' to its original size. So far my method has been to try and load a gif of this growth animation on the mouseEnter event and then load a shrink animation on the mouseLeave, but this just loops the respective gif over and over. How can i get the gif to play once only?
i tried loading the frames sequentially with a thread sleep in between them as well but all i see when i do this is the last image i try to load. here's an example of the code used for this method, where i try to show one image, and then show another after 0.1 seconds
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
((PictureBox)sender).Image =Image.FromFile("C:/Users/michael/Desktop/131.bmp");
Thread.Sleep(100);
((PictureBox)sender).Image = Image.FromFile("C:/Users/michael/Desktop/131a.bmp");
}
Also is there a way to do this without a gif, such as by using a for loop to increase the size of the button or picturebox?
EDIT 1:
where do i put the timer stop in so that when i start the second animation, the first one stops?
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
Timer timeraf = new Timer();
timeraf.Interval = 10;
timeraf.Tick += new EventHandler(timerAfwd_Tick);
timeraf.Start();
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
Timer timerab = new Timer();
timerab.Interval = 10;
timerab.Tick += new EventHandler(timerAbwd_Tick);
timerab.Start();
}
If you make your main thread sleep, I'm pretty sure it both locks out user input and it blocks the thread that handles painting. So your image can't paint any animations. Try using a timer like this:
public partial class Animation : Form
{
Image img1 = Properties.Resources.img1;
Image img2 = Properties.Resources.img2;
Image img3 = Properties.Resources.img3;
List<Image> images = new List<Image>();
Timer timer = new Timer();
public Animation()
{
InitializeComponent();
timer.Interval = 250;
timer.Tick += new EventHandler(timer_Tick);
images.Add(img1);
images.Add(img2);
images.Add(img3);
animated_pbx.Image = img1;
}
private void timer_Tick(object sender, EventArgs e)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new EventHandler(timer_Tick));
}
else
{
// Loop through the images unless we've reached the final one, in that case stop the timer
Image currentImage = animated_pbx.Image;
int currentIndex = images.IndexOf(currentImage);
if (currentIndex < images.Count - 1)
{
currentIndex++;
animated_pbx.Image = images[currentIndex];
animated_pbx.Invalidate();
}
else
{
timer.Stop();
}
}
}
private void animated_pbx_MouseEnter(object sender, EventArgs e)
{
timer.Start();
}
private void animated_pbx_MouseLeave(object sender, EventArgs e)
{
timer.Stop();
animated_pbx.Image = img1;
animated_pbx.Invalidate();
}
}
EDIT: Changed code to add a animation when you hover over the PictureBox. The animation will stay on the final frame while you stay hovered. When the mouse leaves, it resets to the 1st frame. You can use any number of frames you want. You should also handle MouseDown and MouseUp, and create 1 more image to show the depressed or "down" state.

How to load an image, then wait a few seconds, then play a mp3 sound?

After pressing a button, I would like to show an image (using a picturebox), wait a few seconds and then play a
mp3 sound, but i dont get it to work. To wait a few seconds I use System.Threading.Thread.Sleep(5000). The problem is, the image always appears after the wait time, but I want it to show first, then wait, then play the mp3... I tried to use WaitOnLoad = true but it doesn't work, shouldn't it load the image first and the continue to read the next code line?
Here is the code I've tried (that doesn't work):
private void button1_Click(object sender, EventArgs e) {
pictureBox1.WaitOnLoad = true;
pictureBox1.Load("image.jpg");
System.Threading.Thread.Sleep(5000);
MessageBox.Show("test");//just to test, here should be the code to play the mp3
}
I also tried loading the image with "LoadAsync" and put the code to wait and play the mp3 in the "LoadCompleted" event, but that doesn't work either...
I would use the LoadCompleted event and start a timer with 5 sec interval once the image is loaded, so that the UI thread is not blocked:
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.WaitOnLoad = false;
pictureBox1.LoadCompleted += new AsyncCompletedEventHandler(pictureBox1_LoadCompleted);
pictureBox1.LoadAsync("image.jpg");
}
void pictureBox1_LoadCompleted(object sender, AsyncCompletedEventArgs e)
{
//System.Timers.Timer is used as it supports multithreaded invocations
System.Timers.Timer timer = new System.Timers.Timer(5000);
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
//set this so that the timer is stopped once the elaplsed event is fired
timer.AutoReset = false;
timer.Enabled = true;
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
MessageBox.Show("test"); //just to test, here should be the code to play the mp3
}
Have you tried using Application.DoEvents(); before the wait time? I believe that should force C# to draw the image before going to sleep.
It works when application.doevents() is used.
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.Load("image.jpg");
Application.DoEvents();
pictureBox1.WaitOnLoad = true;
System.Threading.Thread.Sleep(5000);
MessageBox.Show("test"); //just to test, here should be the code to play the mp3
}

Categories

Resources