RhinoCommon Event handler issue

Hi @Darryl_Menezes,

We always advise developers to not do too much in event handlers, especially document modifications. It’s better to set a flag and then handle the event later in a Rhino.Idle handler.

Here is a pattern I use frequently:

/// <summary>
/// Event handlers
/// </summary>
private EventHandler<DocumentEventArgs> m_new_document;
private EventHandler<DocumentOpenEventArgs> m_end_open_document;
private EventHandler m_idle;

/// <summary>
/// Event type
/// </summary>
enum EventType
{
  None,
  NewDocument,
  EndOpenDocument,
}
private EventType m_event_type;

/// <summary>
/// Hook Rhino events
/// </summary>
private void HookRhinoEvents()
{
  if (null == m_new_document)
    RhinoDoc.NewDocument += m_new_document = OnNewDocument;

  if (null == m_end_open_document)
    RhinoDoc.EndOpenDocument += m_end_open_document = OnEndNewDocument;
}

/// <summary>
/// Unhook Rhino events
/// </summary>
private void UnhookRhinoEvents()
{
  if (null != m_new_document)
  {
    RhinoDoc.NewDocument -= m_new_document;
    m_new_document = null;
  }

  if (null != m_end_open_document)
  {
    RhinoDoc.EndOpenDocument -= m_end_open_document;
    m_end_open_document = null;
  }
}

/// <summary>
/// Hook Rhino.Idle event
/// </summary>
private void HookRhinoIdle(EventType eventType)
{
  if (null == m_idle)
  {
    m_event_type = eventType;
    RhinoApp.Idle += m_idle = OnIdle;
  }
}

/// <summary>
/// Unhook Rhino.Idle event
/// </summary>
private void UnhookRhinoIdle()
{
  m_event_type = EventType.None;
  if (null != m_idle)
  {
    RhinoApp.Idle -= m_idle;
    m_idle = null;
  }
}

/// <summary>
/// RhinoDoc.NewDocument event handler
/// </summary>
private void OnNewDocument(object sender, DocumentEventArgs args)
{
  HookRhinoIdle(EventType.NewDocument);
}

/// <summary>
/// RhinoDoc.EndNewDocument event handler
/// </summary>
private void OnEndNewDocument(object sender, DocumentOpenEventArgs args)
{
  HookRhinoIdle(EventType.EndOpenDocument);
}

/// <summary>
/// RhinoApp.Idle event handler
/// </summary>
private void OnIdle(object sender, EventArgs e)
{
  switch (m_event_type)
  {
    case EventType.NewDocument:
      {
        // todo
      }
      break;
    case EventType.EndOpenDocument:
      {
        // todo
      }
      break;
  }
  UnhookRhinoIdle();
}

Hope this helps,

– Dale

3 Likes