Event difference between IDE and optimised

agraham

Expert
Licensed User
Longtime User
You will probably say this is illegal but the attached B4ppc code raises one button click event in the IDE and two when optimised compiled.
B4X:
Sub Globals
   'Declare the global variables here.
End Sub

Sub App_Start
   Form1.Show
   AddEvent("button1", click, "Click")
End Sub

Sub Button1_Click
End Sub

Sub Click
   Msgbox(Sender & " - click")
End Sub
The reason being that the use of a hashtable to connect events to controls assumes only one event per control action exists. Here the existing event delegate isn't removed from the control so that gets called as well as the new one and both are vectored to the same sub. To handle Thread events in my FormEx I removed the original events by
B4X:
EventInfo ei = threadobj.GetType().GetEvent("ThreadEvent", BindingFlags.IgnoreCase | BindingFlags.Public
    | BindingFlags.Static | BindingFlags.Instance);
if (ei != null)
{
    // can only get the delegates via a Field access
    FieldInfo field = threadobj.GetType().GetField("ThreadEvent", BindingFlags.NonPublic | BindingFlags.Instance);
    EventHandler eh = field.GetValue(threadobj) as EventHandler;
    //ei.RemoveEventHandler(threadobj,dels[0]); //could remove a single event
    MethodInfo mi = ei.GetRemoveMethod();
    foreach (Delegate del in eh.GetInvocationList()) // remove all
        ei.GetRemoveMethod().Invoke(threadobj, new object[] { del });
    ei.AddEventHandler(threadobj, new EventHandler(this.ThreadEvent));
}
else
    throw new Exception("Event does not exist in object.");
I did that as the event handler was different. In this case, as there is a common event handler the AddEventHandler() could be skipped if an event already exists.
 

agraham

Expert
Licensed User
Longtime User
Basic4ppc events model allows only one event per control (unlike the .Net events which are MulticastDelegates).
Yes, I already said that.
There are very few situations that require assigning several listeners to a single control event.
Sorry but that wasn't the point I was trying to make. I was trying so say that as B4ppc only allows one event Sub per control event why not allow AddEvent to cleanly change that event if required in the optimised compiler (as it seems to do in the IDE) which wouldn't be difficult to do.
 

agraham

Expert
Licensed User
Longtime User
AFAIK there is no simple way to remove all event handlers..
It's in that code above! ( or below now :) )
B4X:
    // can only get the delegates via a Field access
    FieldInfo field = threadobj.GetType().GetField("ThreadEvent", 
           BindingFlags.NonPublic | BindingFlags.Instance);
    EventHandler eh = field.GetValue(threadobj) as EventHandler;
    //ei.RemoveEventHandler(threadobj,dels[0]); //could remove a single event
    MethodInfo mi = ei.GetRemoveMethod();
    foreach (Delegate del in eh.GetInvocationList()) // remove all
        ei.GetRemoveMethod().Invoke(threadobj, new object[] { del });
 
Top