I would like to fire my code based on a selected value from a drop down list of values.I want to also specify a time range (example below). The code I want to fire is behind button1_Click so id want to click that via code.
//Create the timer
Timer timer = new Timer();
//set it up
timer.Tick += new EventHandler(timer_Tick);
timer.Interval = (1000 * 60 * 5);
timer.Enabled = true;
timer.Start();
//now do stuff
void timer_Tick(object sender, EventArgs e)
{
//click the button using code
}
Lets say I select 8 from the drop down list, that means I want to click my button 8 times, HOWEVER, the button needs to be clicked equally based on a time range.
So lets say I select:
From: 13:00
To: 15:00
that gives me 3 hours. I then want to divide the number that I have selected from the drop down, eg 8 by the number of hours/mins available.
In the example I expect the button to be clicked every 22.5mins.
On the SelectedValueChanged, reset the timer. Stop it, reset the interval and start it again. Inside the event handler, execute the click method.
Related
I have several buttons, and I want them to do something when the cursor has been positioned over them for an already specified time. In this case they should just write their content in a textbox.
This is the Timer:
private static System.Timers.Timer myTimer =
new System.Timers.Timer(1500);
This is the method the buttons execute with the MouseEnter event:
private void keysHover(object sender, EventArgs e)
{
myTimer.Elapsed += delegate { keysHoverOK(sender); };
myTimer.Enabled = true;
}
And this is what gets executed if the Timer finishes:
private void keysHoverOK(object sender)
{
this.Dispatcher.Invoke((Action)(() =>
{
txtTest.Text += (sender as System.Windows.Controls.Button).Content.ToString();
}));
myTimer.Enabled = false;
}
I don't quite understand why this is happening, but everytime one of the buttons completes the Timer the keysHoverOK method will write as many characters as there have been hovered. For example, if I hover over the button A, it will write A, if I then hover over the button B, it will write AB, thus getting AAB written on the textbox and so on and so forth, the sentence executes as many times as the rest of the buttons have executed the keysHover method, even if they didn't complete the Timer themselves, it's like their content got saved somewhere. Now of course all I want the buttons to do is to write their content and their content only. So do you have an idea of what I'm doing wrong?
Do you mean the MouseEnter event? I'm not aware of any MouseOver event in WPF.
Without a good, minimal, complete code example, it's impossible to know for sure what the problem is. However, based on the small amount of code you've shared and your problem description, it appears that your main issue is that you're sharing a single Timer object with multiple controls. This is exacerbated by the fact that when one control subscribes to the Timer.Elapsed event, it never unsubscribes. So if another control enables the timer (subscribing to the event as well), both controls are notified when the timer interval elapses.
Even a single control is problematic, as it subscribes itself to the event each time the MouseEnter event is raised.
The fix is to disable the timer and unsubscribe from the event when the mouse leaves the bounds of the control, or when the timer interval has elapsed. That might look something like this:
private EventHandler _timerElapsedHandler;
// Subscribed to the MouseEnter event
private void keysHover(object sender, EventArgs e)
{
_timerElapsedHandler = delegate { keysHoverOK(sender); };
myTimer.Elapsed += _timerElapsedHandler;
myTimer.Enabled = true;
}
// Subscribed to the MouseLeave event
private void keysLeave(object sender, EventArgs e)
{
DisableTimer();
}
private void keysHoverOK(object sender)
{
this.Dispatcher.Invoke((Action)(() =>
{
txtTest.Text += (sender as System.Windows.Controls.Button).Content.ToString();
}));
DisableTimer();
}
private void DisableTimer()
{
myTimer.Elapsed -= _timerElapsedHandler;
myTimer.Enabled = false;
_timerElapsedHandler = null;
}
Other comments:
You should cast instead of using as. Only use as when a reference can legitimately be of a different type than you are checking for. Use a cast when it is always supposed to be the type you are checking for. That way, if you have a bug, you will get a meaningful exception, instead of just some NullReferenceException
The above example fixes the problem with the least disruption to your code. But really, I would make other changes too. For example, rather than storing the delegate in a field, I would just get the Content.ToString() value and store that. Then instead of using an anonymous method for the delegate instance, I would use a named method that simply uses the stored string value to append to the Text property. You can subscribe and unsubscribe the named method by name; the delegate type does the right thing even though it's using a different delegate instance for the subscribe and the unsubscribe.
Another change you might consider making is to use a different Timer instance for each control. Then you don't have to subscribe or unsubscribe as the mouse events occur; just subscribe during initialization.
Finally, especially as this is WPF code, you really should consider storing the appended text in an observable property (e.g. DependencyProperty, or implement INotifyPropertyChanged), and bind it to the txtTest.Text property rather than manipulating that property directly.
I'm assuming when you say:
This is the method the buttons execute with the MouseOver event:
You might mean the MouseEnter event?
From what I see:
You have one central timer
It will start the elapsed count down on the first button you enter
You have not stopped the timer if you leave that button before it elapses
You seem only to add delegates to the event without removing any
The code segment myTimer.Elapsed += delegate { keysHoverOK(sender); }; adds another delegate to the list of already added delegates. It does not replace the list with just one delegate.
If you leave the button before the timer elapses you need to remove the delegate from the timer elapsed event using the minus-equal operator (myTimer.Elapsed -= ....), and then stop the timer. Here you have a problem that you've created an anonymous method so you'd need:-
Research into removing anonymous methods
or
Research into removing all event handlers
or possibly the simplest menthod
Stop and destroy any running timer and create a new timer instance each time you enter the button.
I'm creating a WP8 game with overlaying XMAL for the interface. I will be using multiple buttons. When the button is clicked, it will do something, and then "cooldown".
The cool down lasts for about 4 seconds and in that 4 seconds the button is not enabled. Every second the counter on the button will go down. Once it gets to 0 it will be enabled again.
I'm not sure how to update the buttons text per second to show the cooldown time. I was thinking of implementing the below
System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0,0,1);
dispatcherTimer.Start();
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
// code goes here
}
Even on a PC, I don't think it would be a good idea to do this for something that could have up to nine buttons, so I definitely don't want to do it on a mobile device.
I'm fairly certain I can go around this using databinding but I just can't figure it out.
Thanks.
Assuming program logic changes a button tag based on something random - but using the UI thread.
Is the Button Tag value reliable to use in a click event? i.e. Will it be the same value as-at the time of the event handler as it was at the time of the click?
If not, what is the best method to pass an event specific parameter into a button click event that will be safe?
Update
Added an example as requested. (Remember this is just theoretical).
Windows.Forms.Timer timer = new Timer();
timer.Interval = 1;
timer.Tick += new EventHandler(timer_tick);
timer.Start();
void timer_tick(object sender, EventArgs e)
{
this.button.Tag = Random.NextInt(100).ToString();
}
void button_click(object sender, EventArgs e)
{
string s = (string)((Button)sender).Tag;
Console.WriteLine("Tag value as at button push: " + s);
}
Put another way, the question boils down to: can events be wedged into the GUI event queue that allow the state of the button to be changed between the button being pushed and the click event handling the push?
Assuming that you are using winforms.
IMHO you can use Tag property to pass control specific parameters but you must also remember that windows forms controls are not thread safe. To make a thread-safe call, you must use InvokeRequired. The following link gives an example to set text for TextBox in a thread-safe way but it should not be very different for Tag property.
http://msdn.microsoft.com/en-us/library/ms171728(VS.80).aspx
Hope this helps.
Hello all of you on stack overflow.
I have Asp.net web application which picks up image from a folder , resize them and dump in other folder. For this i have to click on a button to pick image an work on it very often.
Is there a way to make application run automatically by picking image from folder and working on it and then dump in other folder.
Setting can be like start application and run for five minutes and stop and then wait for 1 minute and then start and run again for 5 minute.
IMPORTANT thing is it should only stop after it has finished resizing and dumping the last image in interval.
this will save me lot of trouble because I have to click on button very frequently and disturb me .
I only want the approach and related LINKS .Lots of them . Please reply.
use a timer control to do this task
timer.Tick += new EventHandler(timer_Tick); // Everytime timer ticks, timer_Tick will be called
timer.Interval = (1000) * (1); // Timer will tick evert second
timer.Enabled = true; // Enable the timer
timer.Start();
void timer_Tick(object sender, EventArgs e)
{
do whatever you want
}
If i want my application to do something every 2hr (eg. pop up a message), how do i do that?
Do i program that set of code under onLoad() or somewhere else?
Assuming WinForms.
You should use Windows Timer Class
Drag and drop timer component to your form.
Set interval to 7200000 (2 * 60 * 60 * 1000) milliseconds.
Subscribe to Tick event (the only event that this component has).
private void timer1_Tick(object sender, EventArgs e)
{
MessageBox.Show("Example");
}
The code inside of timer will be triggered every 2 hours, if UI thread is not blocked.
Check the Timer Control and event Tick
Timer.Tick - MSDN
Use the Timer class and set it up when the application starts.