In some cases I have found, developers unwire event then wire it again like this:
control.Click -= new eventHandler(eventHandler)
control.Click += new eventHandler(eventHandler)
why do they do that?
Possibly because there is other code in between that will trigger the event, and they don't want eventHandler to act on it. IMHO this isn't the best way to do things, but it's easy and it works.
If there is no other code in between there cannot possibly be a reason to remove and add the same event handler again.
I can explain this in a simple screnerio.
Imagine you have a "button1"
And you added the event on the run-time.
But once this button is clicked. The process behind it take let say "3Mins" to complete.
And you don't want the user to click this button again.
So you can do by Unwiring it in the first time.
So that the person don't click the button again and again. And adding the instruction in the queue.
If you call code that wires an event, and you don't wont to accidentally wire it up again if it was already wired, you can unwire, and then rewire it. This is the code sample above.
If it wasn't already wired in the first place, no error is thrown. But if the code had already been run first, you don't wont the event to run twice. Thus, unwire and then rewire.
Related
I have found several times that for some reason (for instance, Copy&Paste in the form designer), the Event Handlers assigned to some of the components of a form get lost, i.e., the events are not connected to the correct function in the code of the form.
I would like to check this from either the form code, or from some unit test: ensure that they are not empty at least, or check that they are connected to the correct event handler.
I have seen the questions regarding this, but I can't pass the error The event 'SomeEvent' can only appear on the left hand side of += or -=. This happens when trying to compare it to null, or even as some other answers suggest, get the list of delegates and then check those.
I'm not trying to mess with the events. On the contrary, I want to ensure that they are correctly set from my unit tests.
Manually subscribing the event handlers to the events of the components in the constructor, for instance, seems like a bad idea to me. They should already be subscribed in the InitializeComponent() code... and checking if they are or not to subscribe them is exactly the problem I want to solve.
The event handlers I want to check are NOT defined in the Form itself, i.e., they are not my event handlers, but event handlers for the Form, or some of the components. For example, I have a KeyDown event handler for the Form, to check for some shortcuts. Trying to get the InvocationList for such even handler results in the error above.
I try to never relay on designer to bound events to code, i prefer to write it in my constructor, calling a "WireEvents()" method if i want to group them togheter
Anyway, if i've understood your question, you could just iterate over the eventhandler attached delegates
any EventHandler / EventHandler<> has a method GetInvocationList() that return the list of attached event delegates so you can use that to do your checks
you can iterate doing something like
if(YourEvent!=null){
foreach (var #delegate in YourEvent.GetInvocationList()){
//do your job
}
}
update:
here the link to another answer that address your problem of not being able to call GetInvocationList: https://stackoverflow.com/a/12476529/1716620
I have a scenario is which I need to fire the SelectedIndexChanged event of a winform's combox even when the old and new index is same.. I can not use SelectionChangeCommited because the values are being set programmatically .. and it wont get fired. Is it by any chance to force 'SelectedIndexChanged' to fire even when old and same index are same?
It seems wierd that you want the event to refire for the same item. It's probably because you just want to reexecute the event handler logic. Why dont you extract the SelectionChanged logic into a new method and call that one programmatically?
Nothing prevents you from calling event handler directly:
comboBox1_SelectedIndexChanged(comboBox1, new EventArgs()); // or (null, null)
But solution of atomaras is a better (nicer) way to do it.
I myself dislike to use standard components in more-less serious software. Instead I subclass all standard components from very beginning and adding functionality to them as soon as I need it without needs to change anything in the existing forms.
In this case I'd add a public event riser OnSelectedIndexChanged to execute event (to run code inside event handler programmatically).
combobox.selectedIndex = value;
combobox.selectedevent(null,null);
I'm implementing a module which needs to handle both MouseClick and MouseDoubleClick on a ChartControl of DevExpress. The version that I'm using is v12.2.
When I double click on that chart, both events are fired. I'd like (and I think that it must be) it just fires one event, in this case, MouseDoubleClick.
So, anyone know how to fix that problem?
What's I've tried:
Handle MouseClick or Click event and see MouseEventArgs#Clicks property. But it's always 1.
What's I'm using:
Declare a boolean variable to tell if MouseDoubleClick is fired. On MouseClick handling, just waiting for a moment, then do the codes if that variable does not turn on. I think this is a bad implementation.
You need a time machine to see the difference between the two. Inevitably a double-click starts with a single click, you always see the first click first.
You can get a time machine that sees the future by using a timer that delays the past. Set its interval to SystemInformation.DoubleClickTime + 16 and start it in the Click event, stop it in the DoubleClick event. If the Tick event fires then it was a single click.
That works, but do note that the delayed response to a single click is fairly annoying. Best not to annoy your user with a user interface like that.
I have a MVVM application in WPF. I have an event that gets dispatched from a static instance of a class.
When a given condition occurs, I need to listen for the next occurrence of said event. I do this with the following code:
myInstance.OnData += myEventHandlerInstance;
The event handler is removed at a later time, but as soon as it is added, the event handlers in the other view models no longer execute. I have verified that the dispatcher is the same instance in all places where the event is fired and handled (using the methods described below).
Why does the existing handler not get executed?
delete this line:
myInstance.OnData -= new EventHandler(myInstance_onData);
Why were you doing this? You should get the original event handler and remove that. Also, you should do this outside the event handler itself.
You'll have to put in something like this, to ensure that your code is executing on the right thread:
if(Dispatcher.CurrentDispatcher.CheckAccess())
{
<Code here>
}
else
{
Dispatcher.CurrentDispatcher.Invoke(<Code here>)
}
Thanks for the help everyone. You helped me focus in on the problem. The problem was purely a structure/logic issue, I was able to dig deeper into the code.
Somebody know the VListBox?
It is fast to load item to the listbox.
But I can't get the SelectIndexChanged Event be triggered by set SelectIndex.
Somebody know how to trigger that event by winapi or something else?
VlistBox source code is in the page above.
does the event get fired when you click on the item with a mouse?
if so then it may be by design. also if you are selecting it via code then a better way is not "how to manually trigger the event". consider refactoring the event handling code into a new DoSelectionChanged() method and have the code that calls SelectIndex() call that. in this way the "meaty" stuff that normally would be in an event callback can be used by other methods, not just the callback.
hope that helps
Wy don't you call the EventHandler manually?
vListBox1_selectedIndexChanged(null,null);