In versions prior to 3ds Max 2010, performing MAXScript garbage collection can delete the DotNet event handlers too early.
With this method available in 3ds Max 2010 and higher, this can be avoided by setting the life time control of the corresponding objects to be handled by DotNet instead of MAXScript.
dotNet.setLifetimeControl {<dotNetObject> | <dotNetClass>} {#mxs | #dotnet}
Controls whether the MAXScript value wrapping the DotNet object or DotNetclass can be garbage collected when there are no MAXScript references to the value ( #mxs
), or whether the DotNet object is destroyed before the MAXScript value can be garbage collected ( #dotnet
).
By default, a dotNetObject value holds a strong reference to the DotNet object, and the DotNet object is deleted only when the dotNetObject value is deleted. This is equivalent to specifying #mxs
as second argument in the above method.
If you specify #dotnet
as the second argument, the dotNetObject cannot be collected until the DotNet object is deleted. The dotNetObject value holds a weak reference to the DotNet object and the DotNet object is deleted when no other DotNet objects hold a reference to it and a DotNet garbage collection occurs.
EXAMPLE 1 - HANDLERS DELETED
( function whenButtonIsPressed = ( print "Pressed from a .NET button" ) function formIsClosed = ( print "form closed" ) local mButton = dotNetObject "System.windows.forms.button" mButton.text = ".NET Button" mButton.size = dotNetObject "System.Drawing.Size" 100 100 mButton.location = dotNetObject "System.Drawing.Point" 50 50 local hForm = dotNetObject "System.Windows.Forms.Form" hForm.controls.add mButton dotNet.addEventHandler mButton "click" whenButtonIsPressed dotNet.addEventHandler hForm "Closed" formIsClosed hForm.show() ok ) gc()
Evaluating the above code creates a DotNet Form with a DotNet button and two event handlers - one to print a message to the Listener when the button is pressed and one to print a message when the Form is closed.
Because of the MAXScript Garbage Collection performed after the creation of the Form, both handlers are deleted immediately and nothing is printed when pressing the button or closing the form.
EXAMPLE2 - HANDLERS PRESERVED
By switching the life time control of the button and the form to DotNet, it is ensured that the event handlers of both buttons are preserved after a MAXScript Garbage Collection:
( function whenButtonIsPressed = ( print "Pressed from a .NET button" ) function formIsClosed = ( print "form closed" ) local mButton = dotNetObject "System.windows.forms.button" mButton.text = ".NET Button" mButton.size = dotNetObject "System.Drawing.Size" 100 100 mButton.location = dotNetObject "System.Drawing.Point"50 50 local hForm = dotNetObject "System.Windows.Forms.Form" hForm.controls.add mButton dotNet.addEventHandler mButton "click" whenButtonIsPressed dotNet.addEventHandler hForm "Closed" formIsClosed dotNet.setLifetimeControl mButton #dotnet dotNet.setLifetimeControl hForm #dotnet hForm.show() ok ) gc()