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);
}
Related
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;
}
Im trying to get a smooth expanding and collapsing animation for my form. My current animation is really jittery and non consistent. Heres a Gif of the Animation. Is there another way to do this that doesnt freeze the form?
private void ShowHideToggle_CheckStateChanged(object sender, EventArgs e)
{
if (ShowHideToggle.Checked) //checked = expand form
{
ShowHideToggle.Text = "<";
while (Width < originalWidth)
{
Width++;
Application.DoEvents();
}
}
else
{
ShowHideToggle.Text = ">";
while(Width > 24)
{
Width--;
Application.DoEvents();
}
}
}
Create a Timer:
Timer t = new Timer();
t.Interval = 14;
t.Tick += delegate
{
if (ShowHideToggle.Checked)
{
if (this.Width > 30) // Set Form.MinimumSize to this otherwise the Timer will keep going, so it will permanently try to decrease the size.
this.Width -= 10;
else
t.Stop();
}
else
{
if (this.Width < 300)
this.Width += 10;
else
t.Stop();
}
};
And change your code to:
private void ShowHideToggle_CheckStateChanged(object sender, EventArgs e)
{
t.Start();
}
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();
}
}
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 would like to set a textbox text to "blink" by changing text colors when a button is clicked.
I can get the text to blink how I want it to, but I want it to stop after a few blinks. I cannot figure out how to make it stop after the timer fires a few times.
Here is my code:
public Form1()
{
InitializeComponent();
Timer timer = new Timer();
timer.Interval = 500;
timer.Enabled = false;
timer.Start();
timer.Tick += new EventHandler(timer_Tick);
if (timerint == 5)
timer.Stop();
}
private void timer_Tick(object sender, EventArgs e)
{
timerint += 1;
if (textBoxInvFooter.ForeColor == SystemColors.GrayText)
textBoxInvFooter.ForeColor = SystemColors.Highlight;
else
textBoxInvFooter.ForeColor = SystemColors.GrayText;
}
I know my problem lies with how I'm using the "timerint", but I'm not sure where to put it, or what solution I should use...
Thank you for all your help!
You just have to put the timer check inside the Tick handler. You can access the Timer object by using the sender argument of the handler.
private void timer_Tick(object sender, EventArgs e)
{
// ...
timerint += 1;
if (timerint == 5)
{
((Timer)sender).Stop();
}
}
Here's the complete code that I would use to solve your issue. It correctly stops the timer, detaches the event handler, and disposes the timer. It disables the button during the flashing, and also restores the colour of the textbox after the five flashes are complete.
The best part is that it is purely defined within the one lambda, so no class-level variables required.
Here it is:
button1.Click += (s, e) =>
{
button1.Enabled = false;
var counter = 0;
var timer = new Timer()
{
Interval = 500,
Enabled = false
};
EventHandler handler = null;
handler = (s2, e2) =>
{
if (++counter >= 5)
{
timer.Stop();
timer.Tick -= handler;
timer.Dispose();
textBoxInvFooter.ForeColor = SystemColors.WindowText;
button1.Enabled = true;
}
else
{
textBoxInvFooter.ForeColor =
textBoxInvFooter.ForeColor == SystemColors.GrayText
? SystemColors.Highlight
: SystemColors.GrayText;
}
};
timer.Tick += handler;
timer.Start();
};