I am gathering all the routed events fired for the MouseRightDownButton and storing them in a Queue. I have the Sender object as well as the RoutedEventArgs.
Now, I need to fire those events one by one and with a little pause. I also want to update the UI as I fire each event.
Do this require the Timer class?
Yes it will require a timer of some sort. I would check out the DispatcherTimer class if you need to update objects on the UI.
Related
I have an application written in c#. I have a class (say called ClassA) that has a simple event (code below). The event is raised to keep the user updated on the progress of the code.
public delegate void MyDelegateProgessUpdate(string value);
public event MyDelegateProgessUpdate ProgressUpdate;
When the application is running a list of ClassA objects are created (up to a maximum of 8). So all 8 objects will be raising an event (in their own class) - this works fine as I have just tested it. However I was wondering if two objects raised an event at the same time if there would be an issue?
Edit
I should have mentioned the following details. The list of ClassA objects will all be running at the same time so it is possible the events could be raised at the same time.
Task[] myTasks = new Task[numThreads];
for (int i = 0; i < myTasks.Length; i++)
myTasks [i] = Task.Factory.StartNew(ClassA[i].DoSomeWork, someData[i]);
This is all being done on a background worker thread. When an event is raised a property on my WPF UI is updated and its OnPropertyChanged event called.
The answer depends solely on the code (your code) that is executed by the events:
IF the code itself is threadsave then no there is no issue. If the code is not 100% threadsave then yes you have a possible problem at your hands (a racing condition to happen).
By itself there is no intricate problem with multiple objects raising the same event. It only depends on the code of the event itself and if the objects have the rights to raise the event.
For example if you are in your own thread and try to raise an event on the GUI which runs in its own thread, then you need to use invoke else you will have a problem
That is if you have code that raises events pretty fast (like multiple handlers set to one event, ....) where your code example doesn't go into details there that show how the events are raised (and how you raise the multiple events)
How will two objects raise events at the same time?
From the code and description you have provided, the is nothing to suggest this is actually multi-threaded code, and your events will be processed in the order that they are raised.
If you do have multiple threads, the important thing to remember is that the event handlers will be run on the thread that raised the event, so be careful if you need to modify any user interface items, and synchronize any access to resources being shared between the threads.
Edit:
I can't really comment with regards to WPF, as my experience is mostly Winforms, however this answer appears to pretty comprehensive with regards to managing cross-thread stuff in WPF.
Other than that I wouldn't expect you to have an issue of the events were raised simultaneously, provided they are not sharing a single set of data between them.
ok so I have a form with a button and a combobox,when the form loads I start a new thread. In that thread I want to listen for the click event from the form and get the selected item from the combobox. Whats the best way to go about doing this?
If you do some long running CPU expensive processing on button click, i would recommend to start a new thread every time the button is clicked. The best way would be to listen the click event in the main thread, and when the event fires - start a new thread and pass selected value there.
You can't strictly 'listen' to an event in C#. What you are doing when you attach an event handler to a control is providing a method (as a delegate) that you would like called when the event occurs. Your method will be invoked on whatever thread the invoking class decides to call it on, typically the same thread that the cause of the event happened on. For Windows Forms controls, this is always the UI thread.
In your event handler, you could (and often should) call another method to do the actual work, on another thread. There are many ways of doing this, from manually starting a thread, to the thread pool, to using the TPL.
If you want to have just one thread, that you control, processing all the events, the best idea is having a producer-consumer relationship. Have a queue into which your event handler places an instruction to do work, and have a thread which takes items out of the queue and processes them.
To signal your worker thread to know when there is new work, you can look into AutoResetEvent.
I am building a custom control for a few of my forms which is an "indictor light"; an edit control that just changed color.
I would like to set a timer and see what the "light" looks like when it switches from state to state.
I have been reviewing this link C# Elapsed Timer MSDN
Though this does not work for me. I think the issue has to do with the Timer executing on another Thread meaning I cannot interact with the this (this.editControl.[...]) within the OnTimedEvent method.
Is there a simple Timer I could use to just call a method of a forms controls every second or so?
Use the Timer control (the System.Windows.Forms.Timer class). You can find it in the Toolbox when on a designer canvas.
Set the Interval property to 1000 (1 second) and make sure its Enabled. The Tick event fires at every interval and is raised in the UI thread.
that is a question I have been asking myself for a while.
Giving a certain flow of events, can I when handling one of them, stop the next ones to be raised?
For example, when collapsing a node which child was selected in a treeview (winform), the events are raised like that:
BeforeCollapse
BeforeSelect
AfterSelect
AfterCollapse
I could stop them by using a class member, but I was wondering whether there was a built-in function or just another way (a more elegant way) to achieve this, by acting directly on the events queue.
Any idea?
Not easily, no. The order of the events firing is controlled by the TreeView control class, and there is no built-in way to prevent events from firing. But you have a couple of options:
Create your own TreeView class that inherits from the base class,
then add a bool property to prevent the events from processing.
Then you can override BeforeCollapse, etc. to check the bool
before calling base.BeforeCollapse.
Just create a bool flag, and check the flag in each of the events.
No there is no way to do that for that type of event (you are asking for TreeView).
Like for example could be managed KeyEventArgs.Handled via built-in mechanism.
You can use some instance (boolean ?) value to manage the flow,
or you can, unsubscribe from the event that you don't want more recieve, but after subscribe to it again. Sounds rough solution, but sometimes turns out reasonable one.
even if the event are raised nothing will happen if you don't bind an event handler to them. In this case you can just remove the handler using the code below:
object.Event -= new EventHandlerType(your_Method)
Otherwise you should create your own custom control
according to OnBeforeCollapse you get an TreeViewCancelEventArgs which has an Cancel property. Setting this to true should stop the flow, but will also not collapse it.
Same goes for OnBeforeSelect.
The only times you can easily "cancel" an event is if the event handler has the CancelEventHandler delegate type. Even then it doesn't really cancel it as much as set a flag for the remaining events that makes it skip performing all the events subscribed to it.
If you did have a CancelEventHandler type (which these don't) you'd simply set Cancel to true on the event object itself in the handler.
Plenty of other answers give you suggestions for what you should o. I'd just go with your idea: set a 'event cancelled' flag in your control class, and check it. When the last event in the series gets called, reset it.
What event I should handle to react to the completed change of the TextBox (i.e. when the user is
finished editing the content of the TextBox)?
There are several methods that you can use: Leave event, or a manual "typing stopped" event.
The Leave method is the most straight forward way of doing it, although as the event name suggests, it only happens when they TextBox looses focus, not when the user stops typing.
The TypingStopped event is something you would need to create yourself, but the basic idea of it is a short duration timer (say 500ms, but you would need to test it), which you restart on every KeyDown event of the TextBox. The timer would fire its own event and disable itself if it ever hits the end of it's timeout.
Edit: Updated to Leave event as per Hans' recommendation.
The Leave event is generally a good one for processing user input (for validation for example) as they move on to another part of the form. Just make sure that the event fires if they go from the textbox to any other UI element on your form - you may need to force a focus on the new element.