I have five dice labels and I have a method Roll() that sets their
text value. At the moment when the roll method happens it just makes the numbers appear, but I would like them to look like they are rolling.
Here is what I have
//Roll() simulates the rolling of this die.
public void Roll()
{
if (Active) {
faceValue = random.Next(1, 7);
label.Text = faceValue.ToString();
}
}
Roll() is called from another class like this:
for (int i = 0; i < dice.Length; i++){
dice[i].Roll();
}
My Question is:
How can I let it looks like they are rolling through a set of numbers then stop on a number ?
Try this
public async void Roll()
{
if (Active)
{
for (int i=0;i<20;i++) //Number of rolls before showing final
{
await Task.Delay(100);
label.Text = random.Next(1, 7).ToString();
}
}
}
I tested a Little and this Looks good done in WPF with a DispatcherTimer:
DispatcherTimer timer = new DispatcherTimer();
private void Button_Click(object sender, RoutedEventArgs e)
{
timer.Tick += Roll;
timer.Interval = new TimeSpan(1);
Random r = new Random();
timer.Start();
}
Random r = new Random();
public void Roll(object sender, EventArgs e)
{
increment++;
if (increment >= 250)
{
timer.Stop();
increment = 0;
}
DiceLabel.Content = r.Next(1, 7).ToString();
timer.Interval = new TimeSpan(increment*3000);
}
If you want it faster or longer you can play with the value from:
timer.Interval = new TimeSpan(increment*3000);
here to set the time between the new number is shown.
And for the time to Dice is rolling, you can play with:
if (increment >= 250)
Hope that helps, have fun.
Related
I have a textblock and a button.
I want the textblock to be filled with a random number when I click the button and it should change the random number every 5 seconds. When I click the button a second time it should stop at the last random number.
How do I make this? This is what I tried:
bool thisStatus = false;
private void btn_click(object sender, RoutedEventArgs e)
{
if (thisStatus == false)
{
thisStatus = true;
}
else thisStatus = false;
random();
}
private void random()
{
while (thisStatus)
{
Random random = new Random();
int RandomNumber = random.Next(0, 100);
txtBlck.Text = RandomNumber.ToString();
Task.Delay(5000);
}
}
bool thisStatus = false;
private async void btn_click(object sender, RoutedEventArgs e)
{
thisStatus = !thisStatus // mke the toggling simple.
await random();
}
private async Task random()
{
while (thisStatus)
{
Random random = new Random();
int RandomNumber = random.Next(0, 100);
txtBlck.Text = RandomNumber.ToString();
await Task.Delay(5000);
}
}
you need to await the task delay method because awaiting makes sure it completes before moving on.
You can use the dispatcher Timer
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0,0,5);
int RandomNumber;
Random random = new Random();
private void btn_click(object sender, RoutedEventArgs e)
{
if (thisStatus == false)
{
thisStatus = true;
dispatcherTimer.Start();
}
else {
thisStatus = false;
dispatcherTimer.Stop();
}
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
RandomNumber = random.Next(0, 100);
}
I have a for loop where I calculate the value of something and display it, for example
void Button_Click(object sender, RoutedEventArgs e)
{
InitializeComponent();
Random rand = new Random();
for (i = 0; i <= 30; i++)
{
rnd = rand.Next(1,10);
value += i + rnd;
display.Content = value;
}
}
The problem is, I want to see the value overwritten after each cycle, delayed by X seconds, how could I achieve that in WPF?
Use Task.Delay to execute some code after a period of time.
private async void Button_Click(object sender, RoutedEventArgs e)
{
InitializeComponent();
Random rand = new Random();
for (i = 0; i <= 30; i++)
{
rnd = rand.Next(1,10);
value += i + rnd;
display.Content = value;
await Task.Delay(Timespan.FromSeconds(1));
}
}
What I really want to do, I want to calculate that how many times tick event occur. Actually I want to make check on it that if this event occurs 5 time.
Then messagebox should displayed.
Here is my code :
public partial class MainWindow : Window
{
int i = 0;
int points = 0;
int counter = 0;
public MainWindow()
{
System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(this.playMyAudioFile);
TimeSpan ts = dispatcherTimer.Interval = new TimeSpan(0, 0, 2);
dispatcherTimer.Start();
if (counter == 5)
{
dispatcherTimer.Stop();
}
InitializeComponent();
}
private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
// some code
label1.Content = points;
}
}
private void playMyAudioFile(object sender, EventArgs e)
{
Random rd = new Random();
i = rd.Next(1, 26);
mediaElement1.Source = new Uri(#"D:\Project C#\A-Z\" + i + ".mp3");
mediaElement1.Play();
}
}
Using await, instead of a timer, makes this particular task much easier:
public static async Task makeMusic(TimeSpan timespan)
{
for (int i = 0; i < 5; i++)
{
//this assumes you can remove the parameters from this method
playMyAudioFile();
await Task.Delay(timespan);
}
MessageBox.Show("All done!");
}
You can make the count a parameter, if it needs to be configurable, or remove the timespan as a parameter if it need never change.
Servy's solution is a lot cleaner than using a timer. But if you insist on using a timer, I would suggest this:
private int counter = 0;
private Random rd = new Random();
private void playMyAudioFile(object sender, EventArgs e)
{
i = rd.Next(1, 26);
mediaElement1.Source = new Uri(#"D:\Project C#\A-Z\" + i + ".mp3");
mediaElement1.Play();
++counter;
if (counter == 5)
{
dispatcherTimer.Stop();
}
}
I think that the sender is the dispatcher timer, so you can probably write:
var timer = (DispatcherTimer)sender;
timer.Stop();
And, please, replace this:
TimeSpan ts = dispatcherTimer.Interval = new TimeSpan(0, 0, 2);
With:
TimeSpan ts = dispatcherTimer.Interval = TimeSpan.FromSeconds(2);
When I see new TimeSpan(0, 0, 2), I have to think about what that signifies. Is it minutes, seconds, and milliseconds? Days, hours, and minutes? Hours, minutes, and seconds?
TimeSpan.FromSeconds(2), though, is explicit. There is absolutely no ambiguity.
for(int a=0;a<10;a++)
{
txtblck =txtblk+ a.ToString();
}
In this, txtbox show all the text at the last.
I want to show the text one by one.
You can try this
for (int a = 0; a < 10; a++)
{
txtblck.Text = txtblck.Text + a.ToString();
Application.DoEvents();
System.Threading.Thread.Sleep(1000);
}
This is happening because the for loop is running so fast that you cannot actually see the text of your TextBox changing. Use the System.Threading.Thread.Sleep method to pause the loop for a while so you can watch the text changing:
for(int a = 0; a < 10; a++)
{
txtblck =txtblk + a.ToString();
System.Threading.Thread.Sleep(1000);
}
Try something like this: (I assumed you were using WPF but any timer will do)
System.Windows.Threading.DispatcherTimer timer;
int a, count;
void start() {
timer = new System.Windows.Threading.DispatcherTimer();
a = 0;
count = 10;
timer.Tick += timer_Tick;
timer.Interval = new TimeSpan(0, 0, 1);
timer.Start();
}
void timer_Tick(object sender, EventArgs e) {
updateString();
}
void updateString() {
if (a < count) {
txtblck.Text += a.toString();
a++;
}
else {
timer.Stop();
}
}
I'm trying to create a Windows Form application that searches for a string and has three possible scenarios:
String 1 found - wait
String 2 found - stop
Else - Perform action and wait 1 minute
I am encountering my problem only on the times when it is expected to wait. When this happens, the newTimer_Tick starts to tick every second. I have tried disabling the timer when it ticks and a few other things but none appeared to work. Below is the code:
public void Action(string result)
{
if (result.Contains("string1"))
{
// Check again in 10 + x seconds
int n = new Random().Next(0, 5000);
int newtime = 10000 + n;
newTimer.Tick += new EventHandler(newTimer_Tick);
newTimer.Interval = newtime;
newTimer.Enabled = true;
}
else if (result.Contains("string2"))
{
// Turn off
newTimer.Enabled = false;
}
else
{
// Perform action and tick again in 1min + x seconds
action1();
int n = new Random().Next(0, 5000);
int newtime = 600000 + n;
newTimer.Tick += new EventHandler(newTimer_Tick);
newTimer.Interval = newtime;
newTimer.Enabled = true;
}
}
private void newTimer_Tick(object sender, EventArgs e)
{
Action( result );
}
What have I done wrong?
Each time the following line is called, an new instance of the event handler newTimerTick is added to the invocation list for the Tick event:
newTimer.Tick += new System.EventHandler(newTimer_Tick);
So every time the time tick goes off newTimerTick is going to be called multiple times, which is going to give you unexpected results.
Configure your event handler once only. In the constructor would be a sensible place.
Have you tried to stop the timer with the Timer.Stop method?
Btw: I don't think you need to reassign the Tick event from the newTimer unless you don't create a new Timer everytime.
I think what you were missing is that you have to stop your timer since you don't actually want it to keep for more than one interval. You seem to want to run it once, check on the result and then decide if you want to keep running it or not. Here's the code:
public void action(string result)
{
int n = new Random().Next(0, 5000);
Boolean blActivateTimer = true;
Timer timer = new Timer();
timer.Tick += timer_Tick;
if (!result.Contains("string1") && !result.Contains("string2"))
{
n += 600000;
action1();
}
else
{
if (result.Contains("string1"))
{
n += 10000;
}
else
{
blActivateTimer = false;
}
}
if (blActivateTimer)
{
timer.Start();
}
}
void action1()
{
}
void timer_Tick(object sender, EventArgs e)
{
Timer t = (Timer)sender;
t.Stop();
action(result);
}