Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

developer:dotneteventwatcher [2015/09/14] (current)
Line 1: Line 1:
 +====== Event Watchers ======
 +> **NOTICE:** //The Rhino.NET SDK is deprecated in Rhino 5.  This example adapted for the new RhinoCommon SDK is [[developer:​rhinocommonsamples:​dotneteventwatcher|here]]//​
 +
 +If you have some controls that are using an event watcher to synchronize a control'​s appearance with what is going on in Rhino, please read the following.
 +
 +The virtual function inside your event watcher class potentially could be called from a thread that is NOT your main user interface thread. This happens in the case where a long running command has started a thread to allow a user to cancel a command. A sample case where this occurs is in the contour command and the OnAddObject virtual function.
 +
 +=====Why is this of any interest to you?=====
 +Windows applications can not update any user interface from any thread other than the main UI thread. Changing a Windows Forms control property typically causes the control to immediately update its display. When this happens, windows will crash the application.
 +
 +=====So... what can I do about this?=====
 +If you are updating a control from inside your event watcher virtual function, you should check to see if InvokeRequired on your control is equal to True. If this is the case, you must invoke a delegate to handle your UI updating. This is actually easier than it sounds.
 +
 +Here is a VB.NET sample of OnAddObject inside of your event watcher subclass
 +<code vb>
 +  Public Overrides Sub OnAddObject(ByRef doc As MRhinoDoc, ByRef obj As MRhinoObject)
 +   '​m_ctrl is your windows forms control that you want to update
 +   If( m_ctrl.InvokeRequired ) Then
 +     '​This code is being called inside a non-ui thread. You should not updated your
 +     '​control from this thread
 +   Else
 +     '​It is fine to update your control
 +     ​m_ctrl.Text = "​OnAddObject was called"​
 +   End If
 +  End Sub
 +</​code>​
 +=====But... I really do need to update my control'​s state even when in the wrong thread!=====
 +This is where Invoke or BeginInvoke comes into play. You can tell your control that your want it to run some code in the main UI thread. Here is a VB.NET sample of how to do this. Again this would all be inside of your event watcher subclass.
 +<code vb>
 +  '​delare a delegate
 +  Private Delegate Sub OnAddDelegate( text as String )
 +  Private Sub SetControlText( text as String )
 +    m_ctrl.Text = text
 +  End Sub
 +
 +  Public Overrides Sub OnAddObject(ByRef doc As MRhinoDoc, ByRef obj As MRhinoObject)
 +    If( m_ctrl.InvokeRequired ) Then
 +      m_ctrl.BeginInvoke( New OnAddDelegate(AddressOf SetControlText),​ "​OnAddObject was called"​ )
 +    Else
 +      SetControlText( "​OnAddObject was called"​ )
 +    End If
 +  End Sub
 +</​code>​
 +The above function could be rewritten to just always call the delegate
 +<code vb>
 +  Public Overrides Sub OnAddObject(ByRef doc As MRhinoDoc, ByRef obj As MRhinoObject)
 +    m_ctrl.BeginInvoke( New OnAddDelegate(AddressOf SetControlText),​ "​OnAddObject was called"​ )
 +  End Sub
 +</​code>​
 +
 +{{tag>​Developer dotnet}}
  
developer/dotneteventwatcher.txt ยท Last modified: 2015/09/14 (external edit)