public void AddCommandRangeListener(int eventType, int id, int lastId, EventListener listener, Object owner) { // I must keep a reference to the listener to prevent it from // being garbage collected. I had trouble passing the listener // delegate into C and back (.NET threw a runtime error, Mono // crashed) so I pass the index into the listeners array instead. // Works like a charm so far. // first we check if the listener is already in listeners // this can happen, when RemoveHandler gets called // if found, just set active to true and return foreach (SListener sl in listeners) { if (sl.owner == owner && sl.listener == listener && sl.eventType == eventType) { int index = listeners.IndexOf(sl); SListener tmpsl = sl; tmpsl.active = true; listeners[index] = tmpsl; return; } } listeners.Add(new SListener(listener, owner, eventType)); wxEvtHandler_Connect(wxObject, eventType, id, lastId, listeners.Count - 1); }
//--------------------------------------------------------------------- // This method doesn't do a real disconnect it only sets the active // flag to false, if it finds it in listeners. // MarshalEvent then doesn't call the listener public bool RemoveHandler(EventListener listener, Object owner) { foreach (SListener sl in listeners) { if (sl.listener == listener && sl.owner == owner && sl.active) { int index = listeners.IndexOf(sl); SListener tmpsl = sl; tmpsl.active = false; listeners[index] = tmpsl; return(true); } } return(false); }
//--------------------------------------------------------------------- // All listened-for events are received here. The event code is // mapped to an actual Event type, and then the listener EventListener lsnrtion // is called. private void MarshalEvent(IntPtr wxEvent, int iListener) { // Create an appropriate .NET wrapper for the event object Event e = Event.CreateFrom(wxEvent); // Send it off to the registered listener SListener listener = (SListener)listeners[iListener]; // only iterate through the list if listener.owner != null // Only the new event system can handle more then one EventListener // because the EventListener gets connected via its owner and not // via a Frame, Dialog, etc... if (listener.owner != null) { foreach (SListener sl in listeners) { // continue if listener equals sl, because it will be handled below if (listener.Equals(sl)) { continue; } // if there is the same object in the list with the same // EventType then call its listener also if (sl.owner != null) { if (sl.owner.Equals(listener.owner) && sl.eventType == listener.eventType) { if (sl.active) { sl.listener(this, e); } } } } } if (listener.active) { listener.listener(this, e); } }