I'm working with a Winforms app and I'm tyring to make a label "glide" up when a user clicks on it. To do this, I've created a click event that starts a timer, which then gradually moves the label up the form. I then have a counter that I increment, and when the counter reaches a certain position, the timer should stop. The timer is not stopping, however. I've deliberately set the counter limit to 2 for testing purposes, but the label continues to fly off the form. Here is the code:
private void DrawerTimer_Tick(object sender, EventArgs e)
{
int counter = 0;
newsLabel.Top -= 10;
counter++;
if (counter == 2)
drawerTimer.Stop();
}
private void News_Click(object sender, EventArgs e)
{
drawerTimer.Start();
}
int counter = 0; // here you are setting it 0
newsLabel.Top -= 10;
counter++; // here you are incrementing it by 1
if (counter == 2) // here you are checking for 2, its never going to get there
drawerTimer.Stop();
More than likely you will want to do something like this
private int _counter; // instance field, field to remember your count
private void DrawerTimer_Tick(object sender, EventArgs e)
{
newsLabel.Top -= 10;
counter++; // increment it every tick
if (counter == 2)
drawerTimer.Stop();
}
private void News_Click(object sender, EventArgs e)
{
_counter = 0; // set to zero when start
drawerTimer.Start();
}
Related
Can someone tell me why this do not work?
i want to start a Thread by pressing a key and stops automatically, then he have to make a rest and starts again.
But if i pressing this key then nothing happens.
he have to start void StartFunction, but Thread isnt starting. If i start the Thread on Forms_load then is all fine. but i need this Thread only on pressing a key
private void StartFunction()
{
Thread AB = new Thread(SEARCHING) { IsBackground = true };
AB.Start();
}
private void StopFunction()
{
Thread AB = new Thread(SEARCHING) { IsBackground = true };
AB.Abort();
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.L)
{
StartFunction();
MessageBox.Show("Timer 1 started!");
}
}
int time = 10;
private void timer1_Tick(object sender, EventArgs e)
{
time++;
if (time == 2 && timer1.Enabled)
{
timer1.Stop();
time = 0;
StopFunction();
}
if (time == 2 && !timer1.Enabled)
{
timer1.Start();
time = 0;
StartFunction();
MessageBox.Show("Timer 1 started!");
}
}
You could make it easier for yourself by storing the timer_tick in a variable.
When the variable has reached 120(2 min) stop the timer. First you should start the timer and then:
private void timer1_Tick(object sender, EventArgs e)
{
time++;
if(time == 120 && timer1.Enabled)
{
timer1.Stop();
time = 0;
}
if(time == 60 && !timer1.Enabled){
timer1.Start();
time = 0;
}
}
You can find the timer_tick event at the ptoperties of the timer.
how to slide panel on mouseclick event in c# windows application
i have tried this
panel1.Location = new Point(panel1.Location.X - i, panel1.Location.Y);
System.Threading.Thread.Sleep(10);
If I understood you correctly, you want to move panel to the left. In that case you can write something like this:
private void panel1_MouseClick(object sender, MouseEventArgs e)
{
//declare step in pixel which will be used to move panel
int xMoveStep = 3;
//repeat this block of code until panel is hidden under form's left border, until
//panels top right is less than 0
while (this.panel1.Right > 0)
{
//move it to left
this.panel1.Left = this.panel1.Left - xMoveStep;
//pause for 10 milliseconds
Thread.Sleep(10);
}
}
You should use Timer and on each tick just make some manipulations on the object.
Timer m_Timer = null; // placeholder for your timer
private void panel1_MouseClick(object sender, MouseEventArgs e)
{
if(m_Timer != null) return;
// if timer is not null means you're animating your panel so do not want to perform any other animations
m_Timer = new Timer(); // instantiate timer
m_Timer.Interval = 1000 / 30; // 30 frames per second;
m_Timer.Tick += OnTimerTick; // set method handler
m_Timer.Start(); // start the timer
}
int m_CurrentFrame = 0; // current frame
void OnTimerTick(object sender, EventArgs e)
{
const int LAST_FRAME_INDEX = 150; // maximum frame you can reach
if(m_CurrenFrame > LAST_FRAME_INDEX) // if max reached
{
m_Timer.Stop(); // stop timer
m_Timer.Dispose(); // dispose it for the GC
m_Timer = null; // set it's reference to null
m_CurrentFrame = 0; // reset current frame index
return; // return from the event
}
this.Invoke(new MethodDelegate( () => { // invoke this on the UI thread
panel1.Location = new Point(panel1.Location.X - m_CurrenFrame, panel1.Location.Y);
});
m_CurrentFrame++; // increase current frame index
}
This should work, please try this code
private void frmTest_MouseMove(object sender, MouseEventArgs e)
{
if (e.Location.X >= panel1.Bounds.X && e.Location.X <= (panel1.Bounds.X + panel1.Bounds.Width) && e.Location.Y >= panel1.Bounds.Y && e.Location.Y <= (panel1.Bounds.Y + panel1.Bounds.Width))
{
panel1.Visible = false;
}
else
{
panel1.Visible = true;
}
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
panel1.Visible = false;
}
Am new to C# and i need your help on this, I want to display one character at a time in a textbox this is my code
private void timer1_Tick(object sender, EventArgs e)
{
int i = 0; //why does this don't increment when it ticks again?
string str = "Herman Lukindo";
textBox1.Text += str[i];
i++;
}
private void button1_Click(object sender, EventArgs e)
{
if(timer1.Enabled == false )
{
timer1.Enabled = true;
button1.Text = "Stop";
}
else if(timer1 .Enabled == true )
{
timer1.Enabled = false;
button1.Text = "Start";
}
}
why does this don't increment when it ticks again?
Because your variable i is local to your event. You need to define it at class level.
int i = 0; //at class level
private void timer1_Tick(object sender, EventArgs e)
{
string str = "Herman Lukindo";
textBox1.Text += str[i];
i++;
}
On exit of your event, variable i becomes out of scope and looses its value. On the next event it is considered a new local variable with the initialized value of 0.
Next, you should also look for cross threaded exception. Since your TextBox is not getting updated on the UI thread.
The issue with you code is that you are assigning i = 0 with every tick, so it will always be 0 everytime it is used. I would suggest using a class level variable for this.
However, using a variable at class level means you are going to need to reset to 0 at some point, probably each time you start the timer.
A further point is that you are going to want to validate the tick event to ensure you don't try to access an index that doesn't exist (IndexOutOfRangeException). For this I would recommend automatically stopping the timer once the last letter has been printed.
With all that in mind, here is my suggested code:
int i = 0;// Create i at class level to ensure the value is maintain between tick events.
private void timer1_Tick(object sender, EventArgs e)
{
string str = "Herman Lukindo";
// Check to see if we have reached the end of the string. If so, then stop the timer.
if(i >= str.Length)
{
StopTimer();
}
else
{
textBox1.Text += str[i];
i++;
}
}
private void button1_Click(object sender, EventArgs e)
{
// If timer is running then stop it.
if(timer1.Enabled)
{
StopTimer();
}
// Otherwise (timer not running) start it.
else
{
StartTimer();
}
}
void StartTimer()
{
i = 0;// Reset counter to 0 ready for next time.
textBox1.Text = "";// Reset the text box ready for next time.
timer1.Enabled = true;
button1.Text = "Stop";
}
void StopTimer()
{
timer1.Enabled = false;
button1.Text = "Start";
}
I have a counter that onclick should increment 1 and it does that on click, but if I click the button again, it won't increment again. Instead it will be stuck at 1. How can I make it go up if the button is clicked more than once?
protected void submitAnswerButton_Click(object sender, EventArgs e)
{
int counter = 0;
if (mathAnswerTextBox.Text == answer.ToString())
{
answerStatus.Text = "Correct!";
}
else if (mathAnswerTextBox.Text != answer.ToString())
{
answerStatus.Text = "Incorrect";
counter++;
if (counter == 1)
{
incorrectStrikes.Text = counter.ToString();
}
else if (counter == 2)
{
incorrectStrikes.Text = counter.ToString();
}
else if (counter == 3)
{
incorrectStrikes.Text = counter.ToString();
}
}
You would need to make counter outside of the method, such as a field in the class, not a local variable:
private int counter = 0;
protected void submitAnswerButton_Click(object sender, EventArgs e)
{
if (mathAnswerTextBox.Text == answer.ToString())
{
answerStatus.Text = "Correct!";
...
Since this is a web application you'd probably want to store the counter in the session, something like:
Inside Page_Load:
if(!IsPostback)
{
Session["AttemptCount"] = 0
}
And then inside
protected void submitAnswerButton_Click(object sender, EventArgs e)
{
int counter = (int)Session["AttemptCount"];
if (mathAnswerTextBox.Text == answer.ToString())
{
answerStatus.Text = "Correct!";
...
//Make sure you include this on all paths through this method that
//affect counter
Session["AttemptCount"] = counter;
As it stands you counter is a local variable (as in below code) and so every time you click button it will get initialized to 0 and hence you get 1 every time cause it's getting incremented once.
protected void submitAnswerButton_Click(object sender, EventArgs e)
{
int counter = 0;
You'll need to store the value in a more global context, eg ViewState or Session or maybe even a HiddenField for storage of the value.
Conclusio: Web is stateless so you'd need a state-manager.
protected void submitAnswerButton_Click(object sender, EventArgs e)
{
var counter = this.ViewState["foo"] as int; // read it from the ViewState from the previous request, or set it to default(int) = 0 with as
// ... do your routine
this.ViewState["foo] = counter; // write it back to store it for the next request
}
Anyway - this is just valid in a web-context where you are stateless.
If you were in a webform/wpf-context you would rather go for a simple static, or instance-variable, or ... (whatever suits your current need, architecture, ...)
I am making a Q&A program where you have 15 sec to answer a question. The problem is that the progress bar is only filling like 90% and moves to the next question. I can put the code here but I have worked in Dutch so maybe it's difficult to understand.
private void volgendeVraagFormButton_Click(object sender, EventArgs e)
{
//button for going to next question
vraagFormulierProgressBar.Value = 0;
vraagFormulierTimer.Start();
}
private void vraagFormulierTimer_Tick(object sender, EventArgs e)
{
if (vraagFormulierProgressBar.Value < vraagFormulierProgressBar.Maximum)
vraagFormulierProgressBar.PerformStep();
//checks if the value is lower than 15 sec(max)
else
{ //stops the progress if the 15 secs are over and moves to next question
vraagFormulierTimer.Stop();
vraagFormulierProgressBar.Value = 0;
vraagFormulierTimer.Start();
}
}
Here's the same code with variable names in English:
private void nextQuestionFormButton_Click(object sender, EventArgs e)
{
//button for going to next question
questionFormProgressBar.Value = 0;
questionFormTimer.Start();
}
private void questionFormTimer_Tick(object sender, EventArgs e)
{
if (questionFormProgressBar.Value <questionFormProgressBar.Maximum)
questionFormProgressBar.PerformStep();
//checks if the value is lower than 15 sec(max)
else
{ //stops the progress if the 15 secs are over and moves to next question
questionFormTimer.Stop();
questionFormProgressBar.Value = 0;
questionFormTimer.Start();
}
}
Take a look at this: Disabling .NET progressbar animation when changing value?
So try to increment your progress bar by 2, then decrement by 1. That should fix the animation problem
Edit
Also, change this line
if (vraagFormulierProgressBar.Value < vraagFormulierProgressBar.Maximum)
to this
if (vraagFormulierProgressBar.Value + 1 < vraagFormulierProgressBar.Maximum)
Edit 2
OK, I've got it this time. First, set the maximum of your progress bar to 300 and the interval to 1 (You can fix the timing later). Next, replace the timer tick function with this:
if (progressBar1.Value < progressBar1.Maximum - 1)
{
progressBar1.Increment(2);
progressBar1.Increment(-1);
}
else
{
timer1.Stop();
progressBar1.Maximum = 10000;
progressBar1.Value = 10000;
progressBar1.Value = 9999;
progressBar1.Value = 10000;
System.Threading.Thread.Sleep(150);
progressBar1.Value = 0;
progressBar1.Maximum = 300;
timer1.Start();
}
Sorry about using the English names, I copied this out of my test form. Anyway, hope this helps!