I want to do frame animation and not sure should i use AnimationDrawable class for animation.
How do frame animation in Xamarin forms for Android. Is there any other approach? Simple example would be perfect.
I did trick just hiding and unhiding required elements. You could call from DoAnimation from any button click or smth else.
private void DoAnimation()
{
_timer = new System.Timers.Timer();
//Trigger event every second
_timer.Interval = 1000;
_timer.Elapsed += CheckStatus;
//count down 5 seconds
_countSeconds = 5000;
_timer.Enabled = true;
}
private void SpinAnimation()
{
switch (_letterShowState) {
case SomeStateStates.State1:
_pic1.IsVisible = false;
_pic2.IsVisible = true;
_pic3.IsVisible = false;
_letterShowState = SomeStateStates.State2;
break;
}
}
private void CheckStatus(object sender, System.Timers.ElapsedEventArgs e) {
_countSeconds--;
new System.Threading.Thread(new System.Threading.ThreadStart(() => {
Xamarin.Forms.Device.BeginInvokeOnMainThread(() => {
SpinAnimation();
});
})).Start();
if (_countSeconds == 0)
{
_timer.Stop();
}
}
Related
I have an object with a diagonal movement in a form, the initial position is the center, i want to stop the movement when the object is on the corner of the form an return the movement to the initial position, thanks for the help, I have the first movement but i don't now how i can return.
public void functionThread()
{
var timer2 = new Timer();
timer2.Interval = 50;
timer2.Enabled = true;
timer2.Tick += (s, e) => panel1.Location = new Point(panel1.Location.X - 5, panel1.Location.Y - 5);
}
This code makes the panel go from left to right, its starting position is 10,10 (BasePoint) and it will set back the panel once it hits the edge so it can go again. You can also stop the timer once you hit this bool, only change then would be to declare the timer globally, this answer is provided by: Nino
bool HitEdge = false;
Point BasePoint = new Point(10,10);
Timer timer2 = new Timer();
public void functionThread()
{
timer2.Interval = 50;
timer2.Enabled = true;
timer2.Tick += timer2_Tick;
}
private void timer2_Tick(object sender, EventArgs e)
{
if((panel1.Left + panel1.Width) >= this.Width)
{
HitEdge = true;
}
if (!HitEdge )
{
panel1.Left += 15;
}
else
{
panel1.Location = BasePoint;
HitEdge = false;
}
}
Move timer2 declaration out of your function and put into form, like this:
public partial class Form1 : Form
{
System.Windows.Forms.Timer timer2 = new System.Windows.Forms.Timer();
public Form1()
{
}
in your functionThread make method for Tick event, to make code easier to read and maintain
timer2.Tick += Timer2_Tick;
In Timer2_Tick method check for panel's location and stop timer if necessary
private void Timer2_Tick(object sender, EventArgs e)
{
if (panel1.Left == 0 || panel1.Top == 0)
{
timer2.Stop();
}
else
panel1.Location = new Point(panel1.Location.X - 5, panel1.Location.Y - 5);
}
I'm making a memory game and i need to set a timer to reset de images if they don't match but it doesn't work to turn the pictures back to hidden:
//set images
if (clickedLabel != null)
{
var Index = Convert.ToInt32(clickedLabel.Tag);
clickedLabel.Image = icons[Index];
//Check first clicked
if (firstClicked == null)
{
firstClicked = clickedLabel;
return;
}
secondClicked = clickedLabel;
timer1.Start();
}
Method timer1_Tick:
//Timer
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop();
firstClicked = null;
secondClicked = null;
}
This might work :
class YourClass
{
System.Timers.Timer aTimer;
void YourMethod()
{
//code
if (clickedLabel != null)
{
var Index = Convert.ToInt32(clickedLabel.Tag);
clickedLabel.Image = icons[Index];
//Check first clicked
if (firstClicked == null)
{
firstClicked = clickedLabel;
return;
}
secondClicked = clickedLabel;
SetTimer();
}
private static void SetTimer ()
{
//System.Timers.Timer aTimer; at the beginning of your class
aTimer = new System.Timers.Timer (2000); //the time you want in milliseconds
aTimer.Elapsed += OnTimedEvent;
aTimer.AutoReset = false;
aTimer.Enabled = true;
}
}
The AutoReset set to false will make the Elapsed event trigger only once. Then, you do what you want in that event.
private static void OnTimedEvent (Object source, ElapsedEventArgs e)
{
firstClicked = null;
secondClicked = null;
}
You might want to use Stop and Dispose methods on aTimer when you don't need it anymore.
You also should be more specific when posting questions, to be sure to have the help you need :)
I'm a C# newbie_and in programming in general_ and Ι'm trying to build a math quiz app with a countdown timer.
I generate an equation each time the user clicks the start button and I give him a max 60 seconds to answer. The user answers -whether his answer is wrong or right doesn't matter_ and can he/she can click again for a new equation. So I want the timer to reset each time the user is shown a new random equation. So far I've only managed to reset this when the 60sec timespan elapses but even that is not working properly, sometimes it displays 59 or 58 secs instead of 60.
So far reading other questions has't helped me much and the timer confuses me. I also accept suggestions to make my code simpler and more elegant.
Here is my code:
EquationView.xaml.cs
public sealed partial class EquationView : Page
{
DispatcherTimer timer = new DispatcherTimer();
int tick = 60;
int result;
public EquationView()
{
this.NavigationCacheMode = NavigationCacheMode.Enabled;
this.InitializeComponent();
}
private void startButton_Click(object sender, RoutedEventArgs e)
{
// Once clicked then disabled
startButton.IsEnabled = false;
// Enable buttons required for answering
resultTextBox.IsEnabled = true;
submitButton.IsEnabled = true;
var viewModel = App.equation.GenerateEquation();
this.DataContext = viewModel;
result = App.equation.GetResult(viewModel);
timer.Interval = new TimeSpan(0, 0, 0, 1);
//timer.Tick += new EventHandler(timer_Tick);
timer.Tick += timer_Tick;
timer.Start();
DateTime startTime = DateTime.Now;
// Reset message label
if (message.Text.Length > 0)
{
message.Text = "";
}
// Reset result text box
if (resultTextBox.Text.Length > 0)
{
resultTextBox.Text = "";
}
}
private void timer_Tick(object sender, object e)
{
Countdown.Text = tick + " second(s) ";
if (tick > 0)
tick--;
else
{
Countdown.Text = "Times Up";
timer.Stop();
submitButton.IsEnabled = false;
resultTextBox.IsEnabled = false;
startButton.IsEnabled = true;
tick = 60;
}
}
private void submitButton_Click(object sender, RoutedEventArgs e)
{
timer.Stop();
submitButton.IsEnabled = false;
resultTextBox.IsEnabled = false;
if (System.Text.RegularExpressions.Regex.IsMatch(resultTextBox.Text, "[^0-9]"))
{
MessageDialog msgDialog = new MessageDialog("Please enter only numbers.");
msgDialog.ShowAsync();
resultTextBox.Text.Remove(resultTextBox.Text.Length - 1);
//Reset buttons to answer again
submitButton.IsEnabled = true;
resultTextBox.IsEnabled = true;
timer.Start();
}
else
{
try
{
int userinput = Int32.Parse(resultTextBox.Text);
if (userinput == result)
{
message.Text = "Bingo!";
App.player.UpdateScore();
startButton.IsEnabled = true;
}
else
{
message.Text = "Wrong, sorry...";
startButton.IsEnabled = true;
}
}
catch (Exception ex)
{
MessageDialog msgDialog = new MessageDialog(ex.Message);
msgDialog.ShowAsync();
submitButton.IsEnabled = true;
resultTextBox.IsEnabled = true;
timer.Start();
}
}
}
It seems to me that you have at least two significant problems here. One is that your timer will likely give the user more than 60 seconds, due to the inaccuracy in the Windows thread scheduler (i.e. each tick will occur at slightly more than 1 second intervals). The other (and more relevant to your question) is that you don't reset the tick value to 60 except when the timer has elapsed.
For the latter issue, it would be better to simply reset your countdown value when you start the timer, rather than trying to remember everywhere that you stop it.
To fix that and the first issue, get rid of the tick field altogether and change your code to look more like this:
static readonly TimeSpan duration = TimeSpan.FromSeconds(60);
System.Diagnostics.Stopwatch sw;
private void startButton_Click(object sender, RoutedEventArgs e)
{
// Once clicked then disabled
startButton.IsEnabled = false;
// Enable buttons required for answering
resultTextBox.IsEnabled = true;
submitButton.IsEnabled = true;
var viewModel = App.equation.GenerateEquation();
this.DataContext = viewModel;
result = App.equation.GetResult(viewModel);
sw = System.Diagnostics.Stopwatch.StartNew();
timer.Interval = new TimeSpan(0, 0, 0, 1);
timer.Tick += timer_Tick;
timer.Start();
// Reset message label
if (message.Text.Length > 0)
{
message.Text = "";
}
// Reset result text box
if (resultTextBox.Text.Length > 0)
{
resultTextBox.Text = "";
}
}
private void timer_Tick(object sender, object e)
{
if (sw.Elapsed < duration)
{
Countdown.Text = (int)(duration - sw.Elapsed).TotalSeconds + " second(s) ";
}
else
{
Countdown.Text = "Times Up";
timer.Stop();
submitButton.IsEnabled = false;
resultTextBox.IsEnabled = false;
startButton.IsEnabled = true;
}
}
This way, it won't matter exactly when the tick event happens, the code will still correctly compute the actual time remaining and use that for the display and to tell whether the time is up.
I am using timer in form to send a command to a controller after every 3 seconds when user presses button. The timer should stop after user again presses same button. But in my case timer doesn't stop. I am using timer in the following way.
private void autoModeTempBtn_Click(object sender, EventArgs e)
{
System.Timers.Timer tempTimer = new System.Timers.Timer(3000);
tempTimer.SynchronizingObject = this;
tempTimer.AutoReset = true;
if (autoModeTempBtn.Text == "Get Temperature Auto Mode")
{
autoModeTempBtn.Text = "hello";
tempTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTemperatureEvent);
tempTimer.Enabled = true;
}
else /*user presses button second time */
{
tempTimer.Stop();
tempTimer.AutoReset = false;
tempTimer.Enabled = false;
autoModeTempBtn.Text = "Get Temperature Auto Mode";
}
}
private void OnTemperatureEvent(object source, System.Timers.ElapsedEventArgs e)
{
//do something
}
Where I am making mistake?
You are creating your timer new every time you click the button. Create the timer once and just Start/Stop it everytime you click. Also you should use the System.Windows.Forms.Timer instead of the System.Timers.Timer.
var _timer = new Timer() { Interval = 3000 };
private void autoModeTempBtn_Click(object sender, EventArgs e)
{
if (!validateSerialNumber())
return;
if (!_timer.Enabled)
{
_timer.Start();
autoModeTempBtn.Text = "hello";
}
else
{
_timer.Stop();
autoModeTempBtn.Text = "Get Temperature Auto Mode";
}
}
And add this code to your constructor:
_timer.Tick += OnTemperatureEvent;
I'm making a little game in C#
When the score is 100, I want two labels to display for one second, then they need to be invisible again.
At the moment I have in Form1:
void startTimer(){
if (snakeScoreLabel.Text == "100"){
timerWIN.Start();
}
}
private void timerWIN_Tick(object sender, EventArgs e)
{
int timerTick = 1;
if (timerTick == 1)
{
lblWin1.Visible=true;
lblWin2.Visible=true;
}
else if (timerTick == 10)
{
lblWin1.Visible = false;
lblWin2.Visible = false;
timerWIN.Stop();
}
timerTick++;
}
The timer's interval is 1000ms.
Problem = labels aren't showing at all
Timers are pretty new to me, so I'm stuck here :/
Try this :
void startTimer()
{
if (snakeScoreLabel.Text == "100")
{
System.Timers.Timer timer = new System.Timers.Timer(1000) { Enabled = true };
timer.Elapsed += (sender, args) =>
{
lblWin1.Visible=true;
timer.Dispose();
};
}
}
Try multithreaded System.Threading.Timer :
public int TimerTick = 0;
private System.Threading.Timer _timer;
public void StartTimer()
{
label1.Visible = true;
label2.Visible = true;
_timer = new System.Threading.Timer(x =>
{
if (TimerTick == 10)
{
Invoke((Action) (() =>
{
label1.Visible = false;
label2.Visible = false;
}));
_timer.Dispose();
TimerTick = 0;
}
else
{
TimerTick++;
}
}, null, 0, 1000);
}