Event AnyMethodCalled vb.net - vb.net

I need to run this code after every method is executed:
Debug.WriteLine(System.Reflection.MethodInfo.GetCurrentMethod())
A nice solution would be an event 'AnyMethodCalled' which would be fired after any method is fired. Is there anything like this? Or do I have to add this line to every Sub in my class?

Related

Event triggered Variable in AnyLogic

I want to trigger a variable from false to true when my event is done. Is there like an "on Exit" action area for events? There is only "action" and the variable does not change. Or is there a best way to change my variable?
There is no OnExit code field for Event, as these code fields are only used on process modelling blocks (such as Source, Delay, .....). These blocks typically have a flow through them and give the user the opportunity to trigger actions at certain points of time in this flow.
An Event, on the other hand, is not part of a process flow. It is a simple trigger, like an egg-timer, to execute a piece of code. This piece of code is executed at the exact time when the event triggers, while the simulation time is paused. So when you want something to happen after the code you defined in your Event, just add it at the end of the code.
I attached a screenshot to show you how it could look like to change a variable by an Event:

"Button.performclick()" vs"Call Button_Click(sender, e)"

What is the difference between Button.performclick() vs Call Button_Click(sender, e)? When should I use which one (if it matters in the first place)?
PerformClick is a method by which the control will raise the click event where as Button_Click(sender, e) is the event's method event handler. Both will probably do what are wanting to do.
Personally, I would suggest using the neither and instead wrap the code in the Click event into a sub, then calling the Sub in the Click event and calling the Sub in in lieu of the PerformClick.
Call exists mainly for compatibility when updating older VB6-era code to VB.Net. There's no good reason to use it in VB.Net.
That said, I almost never use performClick(). If I need to manually call the button click code from elsewhere I tend to either just write Button_Click(sender, e) (no Call) or, even better, create a new method to host the button click code, so both the button click event and my other code will call this new method instead.

Cannot Change ObservableCollection during an CollectionChanged Event

Here's the problem:
I have a CollectionChanged Handler Method:
Private Sub LayersChanged(sender As Object, e As Collections.Specialized.NotifyCollectionChangedEventArgs)
If e.ItemCollectionHasNewItems IsNot Nothing Then
SomethingRelatedToE.execute
End If
End Sub
I cant call SomethingRelatedToE.excecute because it effects e's collection which causes a runtime error.
However if the LayersChanged method has completed I can then call SomethingRelatedToE.execute from another method without effecting it.
Is there a way for me to directly move to another method after the LayersChanged method has finished, like a Goto function or another solution to this?
The reason this type of action isn't allowed is because it will usually result in a circular reference. When the collection is modified in the CollectionChanged event, the event will once again be raised, which will again modify the collection.
I would not recommend trying to work around this because it's unusual to have a collection modify itself. Try thinking of a way to do it another way.
If you need to, though, you can try using ThreadPool.QueueUserWorkItem to do your task in another thread. You'll still want to check for possible circular references and watch for race conditions.

Button disable and enable

I have a vb.net based windows application, where when "GO" button is clicked a bunch of data is loaded into DB. So in my application as soon as "GO" button is clicked I want to just disable it and would like to enable it back when the uploading has completed.
Now in my specific method for btnGo_Click() I have:
btnGo.Enabled = False
as first line and
btnGo.Enabled = True
as last line in the same method.
But I fail to understand why the "GO" though appears as being disabled still allows click when processing is going on. Also if I remove the last line, it gets disabled permanently and doesn't allow the click event.
Kindly suggest what am I doing wrong?
Edit (Dated: 25th Jan 2012): I made changes as suggested by our collegues, but I am facing a new issue here. I am facing an issue where the textbox gets updated but not always. I have updated my textbox in "_ProgressChanged" event of the background worker thread. In my case if there is 10 records uploaded. Then there are 10 lines of updates that are expected in the texbox. But only few lines are shown in the textbox. Is it the repaint issue again? Kindly suggest...Because all other things are done as per your suggestion
You're not doing anything wrong. The problem is that the UI doesn't get updated until the code inside of your event handler method finishes executing. Then, the button is disabled and immediately enabled in rapid sequence.
That explains why if you forget to reenable the button control at the end of the event handler method, it is still disabled—because you told it to disable the button in the first line of the method.
This is a classic case of why you should never perform long-running computational tasks inside of an event handler method, because it blocks the UI from being updated. The computation actually needs to happen on a separate thread. But don't try to create the thread manually, and definitely don't try to update your UI from a separate thread. Instead, use the BackgroundWorker component to handle all of this for you automatically. The linked MSDN documentation has a great sample on how to use it.
Disable the button before starting the BackgroundWorker, and then re-enable it in its Completed event, signaling the completion of your database load.
Since you're trying to execute a function that can take some time, I'd advise you to make use of threading. In .NET there's a BackgroundWorker component which is excellent for performing tasks asynchronous.
On button click, invoke the BackgroundWorker like this:
if not bgwWorker.IsBusy then
btnGo.enabled = false
bgwWorker.RunWorkerAsync()
end if
And use the completed event to enable the button again:
Private Sub bgwWorker_DoWork(ByVal sender As System.Object, _
ByVal e As System.ComponentModel.DoWorkEventArgs) _
Handles bgwWorker.DoWork
' Do your things
End Sub
Private Sub bgwWorker_RunWorkerCompleted(ByVal sender As System.Object, _
ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _
Handles bgwWorker.RunWorkerCompleted
' Called when the BackgroundWorker is completed.
btnGo.enabled = true
End Sub
In the example above, I've used bgwWorker as the instance of a BackgroundWorker.
The button click event is handled as soon as the UI thread has idle time.
After you disable your button, the UI thread is keept busy by your code. At the end of your method, you re-enable the button, and after that you exit the method and allow for idle time.
As a consequence, the button will already be enabled at the point in time where the click event is handled, so your click is "recognized".
The solution is, as others already suggested, to use a Backgroundworker.
Dont try to use doEvents() as a solution (never do), since this would be prone to introduce other subtle problems. That said, you can prove the above explanation with some experimental doEvents in your code. You will see that the click is discarded if a doEvents is performed before the button gets re-enabled. On the other hand, performing a doEvents directly after the button.disable (to "update the GUI") will not help if it is executed before the click.
If your btnGo_Click() is ran inside main thread, UI could not be updated correctly inside a time-consuming task.
The best way you can do what you need is running your method in a BackgroundWorker.
I just tried disabling a button, Updateing the form, Sleeping, and enabling it again. It still performed the click (A click that was done while it "slept" with the button disabled) after it was enabled.
I guess forms "remember" clicks.
(EDIT: I did this in C#.)
It's usually not a good idea to manage the state of a submit button. Instead, perform validation on submit.
I would like to add 2 enhancements to the answer generally described here which is to 'do the work in another thread'.
Ensure button.enable=true always gets called
1.a. You should use a try block in button_click . If there is an error in launching the thread, CATCH should re-enable the button.
1.b. The task complete call back should also ensure the button is enabled using try/catch/finally
1.c The task timeout should also re-enable the button
A common error based on exactly the situation described here is rapid-clicker-person clicks the button twice in rapid succession.
This is possible because its possible, even if unlikely, that 2 click messages get queued and processed before the button is disabled. You can not assume the events happen synchronously.
IMHO a best practice is to use a static variable. Initialize it to 0. Set it to one as the very first statement and set it to 0 following the guidelines in POINT 1.
The second statement in button click should simply RETURN/EXIT if the value > 0
If you are using a worker thread, the static variable may have to be located in that code. I would not advise making it a form level variable.
I had a slightly different issue not being able to call click.
I have a routine that turns the UI on/off based on a validation routine.
i will say that I disagree w/ the suggestion to do validation in the submit. The button should not be enabled if we are able to tell the form is invalid.
My issue was that I was calling the validation from several places. One of the calls was the CustomCellDraw event of a grid which was firing very frequently.
So while it appeared that I was simply disabling/enabling the button a few times, I really was doing this almost continually.
I was able to trouble shoot by placing a label on the form and kind of doing a console.log thing. I immediately realized button.Enabled was flickering, which led me down the correct trouble shooting path.
I realize this addresses a different root cause than op described. But it does address the problem the op describes.

How Do You Use Remove Handler

I ma using DevExpress controls (which doesnt matter for this example). I have a lookupEdit control and I never want the EditValue_Changed event to fire. Can I use RemoveHandler to do this? If so can someone give me a code example of doing this? Should I put RemoveHandler in the load event of the user control I am creating? Or does it go in the EditValue_Changed event of the lookupControl?
THIS IS A WINDOWS APP NO POSTBACK....Sorry
You can use RemoveHandler from any event you add to an object within one of your own classes. If the event is defined and being handled within a class you do not have access to, you will not be able to remove its handler events.
It would be instructive to learn where this EditValue_Changed event is firing. If it is firing within your application, then you must have wired it up either in the designer or in the code (which means you should be able to call RemoveHandler without difficulty). If this belongs to a 3rd party library and is auto-configured, you may not have this access.
You can't stop the control from firing the postback, but you can just not wire up an event handler to a control's event. You don't need RemoveHandler to do that; just don't attach to the event... But it seem like the issue is the postback, DevExpress should have a feature in there to fire a client-side event, and keep that all on the client and not have to worry about a server-side postback.
If this doesn't help, could you explain more about the problem?
HTH.
You might be able to subclass the control and override the method(s) that trigger the EditValue_Changed event to fire. If you have access to the source code, find where its being called and if that code can be overridden.