[Closed] Unable to convert: dotNetObject to dotNetObject…?
Ive been creating a lot of tools for the animators here, and Ive been using more and more DotNet to make the UIs more versatile. I decided to try to get some re-use in building these dotnet UIs, but its causing some problems that I just dont understand.
I keep getting -- Unable to convert: dotNetObject:System.Windows.Forms.Button to type: System.Windows.Forms.Control and other similar errors. But heres the awesome part only sometimes. On my larger script, itll happen sometimes 5 times in a row, then randomly run without error! The following test case runs a little more frequently, but it is causing the same error maybe 1 in 5 times.
I think it has something to do with the variables holding references to the values instead of the values themselves? How do I force these variables to hold the correct values? Why is it randomly working and/or not working, but not consistently doing either?
Heres a pared-down version of the script thats causing me problems.
struct zmDotNetUITest (
fn zmAdjTableLayout t colStyles rowStyles =
(
t.columnCount = colStyles.count
t.rowCount = rowStyles.count
--
for i = 1 to colStyles.count do (
t.columnStyles.add (dotNetObject "system.windows.forms.columnstyle")
case colStyles[i][1] of (
#absolute: t.columnStyles.item[(i-1)].sizetype = t.columnStyles.item[(i-1)].sizetype.absolute
#percent: t.columnStyles.item[(i-1)].sizetype = t.columnStyles.item[(i-1)].sizetype.percent
#AutoSize: t.columnStyles.item[(i-1)].sizetype = t.columnStyles.item[(i-1)].sizetype.AutoSize
)
t.columnstyles.item[(i-1)].width = colStyles[i][2]
)
for i = 1 to rowStyles.count do (
t.rowStyles.add (dotNetObject "system.windows.forms.rowstyle")
case rowStyles[i][1] of (
#absolute: t.rowStyles.item[(i-1)].sizetype = t.rowstyles.item[(i-1)].sizetype.absolute
#percent: t.rowStyles.item[(i-1)].sizetype = t.rowstyles.item[(i-1)].sizetype.percent
#AutoSize: t.rowStyles.item[(i-1)].sizetype = t.rowstyles.item[(i-1)].sizetype.AutoSize
)
t.rowStyles.item[(i-1)].height = rowStyles[i][2]
)
),
fn zmDnTableLayout n parent:undefined col:1 row:1 pad:0 border:false =
(
local tabLay = dotnetobject "System.Windows.Forms.TableLayoutPanel"
if border then (
tabLay.cellBorderStyle = tabLay.cellBorderStyle.outset
)
tabLay.columnCount = col
tabLay.rowCount = row
tabLay.dock = tabLay.dock.fill
tabLay.Margin = (dotNetObject "system.windows.forms.padding" pad)
tabLay.padding = (dotNetObject "system.windows.forms.padding" pad)
tabLay
),
fn zmdn_createButton t w h evt tag:undefined =
(
local btn = dotnetobject "System.Windows.Forms.button"
btn.text = t
if (tag!=undefined) then btn.tag = tag
btn.padding = btn.margin = (dotNetObject "system.windows.forms.padding" 2)
if (w==0) then (
btn.dock = btn.dock.fill
) else (
btn.width = w
btn.height = h
)
dotNet.addEventHandler btn evt[1] evt[2]
dotNet.setLifetimeControl btn #dotnet
btn
),
fn zmdnui_form t w h =
(
dotnet.loadassembly "System.Data"
local newFrm = dotnetobject "MaxCustomControls.Maxform"
newFrm.size = dotnetobject "System.Drawing.Size" w h
newFrm.formborderStyle = newFrm.formborderStyle.Sizable
newFrm.text = t
--dotNet.setLifetimeControl newFrm #dotnet
newFrm
)
)
global zmDotNetUITest = zmDotNetUITest()
-- ------------------------------------------------------------------------------------------------
try (zmdnTest.form.close()) catch()
struct zmdnTest (
form,
maxbut,
xafbut,
otherbut,
fn zmpg_btn_evt =
(
format "yo
"
),
fn initUI =
(
zmdnTest.form = zmDotNetUITest.zmdnui_form "animPropagate" 800 400
local mainlay = zmDotNetUITest.zmDnTableLayout "" col:4 row:1 pad:0 border:false
zmDotNetUITest.zmAdjTableLayout mainlay #(#(#absolute,150),#(#absolute,150),#(#absolute,150),#(#percent,100)) #(#(#percent,100))
local laySrc = zmDotNetUI.zmDnTableLayout "" col:1 row:3 pad:0 border:false
zmDotNetUI.zmAdjTableLayout laySrc #(#(#percent,100)) #(#(#percent,100),#(#percent,100))
zmdnTest.maxBut = zmDotNetUITest.zmdn_createButton "Max" 0 0 #("click",zmpg_btn_evt)
zmdnTest.xafBut = zmDotNetUITest.zmdn_createButton "XAF" 0 0 #("click",zmpg_btn_evt)
zmdnTest.otherbut = zmDotNetUITest.zmdn_createButton "Other" 0 0 #("click",zmpg_btn_evt)
mainlay.controls.addRange #(laySrc)
laySrc.controls.addRange #(zmdnTest.maxBut,zmdnTest.xafbut,zmdnTest.otherbut)
form.controls.addRange #(mainlay)
zmdnTest.form.showModeless()
)
)
global zmdnTest = zmdnTest()
zmdnTest.initUI()
It’s mostly happening on the 7th line up from the bottom: “laySrc.controls.addRange …”.
Any help would be greatly appreciated.
rich
i made some minor fixes in the code (they are not related to the issue)…
but i can’t reproduce the problem. and i don’t see anything wrong in your code.
what are the other errors?
I ran your code (actually denis’s fixed code) 50 times and couldn’t reproduce the error.
Thanks for taking a look. I wonder if it’s a memory thing, though I am running Win7 with 8GB… the name mismatch in the scripts above was because I copy/pasted those chunks from my original, longer script.
So I evaluated this script about 10 times without error, then it failed about 10 times in a row, then worked once, then failed about 3-4 more times, then worked again.
Here’s the full error dump from the debugger window.
#
-- Unable to convert: dotNetObject:System.Windows.Forms.Button to type: System.Windows.Forms.Control
** thread data: threadID:6628
** ------------------------------------------------------
** [stack level: 0]
** In InitUI(); filename: C:\Users\rkatz\AppData\Local\Autodesk\3dsMax\2010 - 64bit\enu\scripts\samplestructDN.ms; position: 3548; line: 93
** member of: StructDef:zmdnTest
-- Locals:
-- mainlay: dotNetObject:System.Windows.Forms.TableLayoutPanel
-- laySrc: dotNetObject:System.Windows.Forms.TableLayoutPanel
-- Externals:
-- zmpg_btn_evt: Struct member:zmpg_btn_evt : zmpg_btn_evt()
-- zmdnTest: Global:zmdnTest : (zmdnTest form:dotNetObject:MaxCustomControls.MaxForm maxBut:dotNetObject:System.Windows.Forms.Button xafBut:dotNetObject:System.Windows.Forms.Button otherbut:dotNetObject:System.Windows.Forms.Button)
-- form: Struct member:form : dotNetObject:MaxCustomControls.MaxForm
-- zmDotNetUITest: Global:zmDotNetUITest : (zmDotNetUITest)
-- owner: (zmdnTest form:dotNetObject:MaxCustomControls.MaxForm maxBut:dotNetObject:System.Windows.Forms.Button xafBut:dotNetObject:System.Windows.Forms.Button otherbut:dotNetObject:System.Windows.Forms.Button)
-- Owner:
-- Locals:
-- this: (zmdnTest form:dotNetObject:MaxCustomControls.MaxForm maxBut:dotNetObject:System.Windows.Forms.Button xafBut:dotNetObject:System.Windows.Forms.Button otherbut:dotNetObject:System.Windows.Forms.Button)
-- xafBut: dotNetObject:System.Windows.Forms.Button
-- form: dotNetObject:MaxCustomControls.MaxForm
-- otherbut: dotNetObject:System.Windows.Forms.Button
-- maxBut: dotNetObject:System.Windows.Forms.Button
** ------------------------------------------------------
** [stack level: 1]
** called from top-level
The “Other similar error” I was referring to was, if you notice there’s an optional “tag” parameter to the createButton function. Sometimes I’ll pass a textbox or a form in that parameter to embed in the control’s tag property, and that was sporadically giving me errors too like “can’t convert System.Windows.Forms.TextBox to type System.Object”.
Yes, I just verified that it is happening on other people’s machines as well, but much less frequently than mine.
what do all the machines that failed have in common? max version? OS verison? dotnet version? 3rd party maxscript extensions?
I think I figured it out. I found this post from a couple months back:
http://forums.cgsociety.org/showthread.php?f=98&t=962876#post6900295
I commented out the dotnet.setLifetimeControl calls in the functions that build the UI, and added a loop at the end of the initUI() function that iterates through all of the controls AFTER the form.showModeless() and calls setLifetimeControl #dotnet on them. Now it works.
I was ending up with these “phantom” values in the variables that were holding the DotNet controls. If you typed classof myVar in listener, it would say “DotNetObject”. If you just typed myVar into listener, it would say “DotNetObject: System.Windows.Forms.Button”. But if you tried to access any properties of the button, it would say that the property didn’t exist. And of course when I tried to add a button to a layout, it would say it can’t convert button to control (its parent class).
Though I’m not exactly sure why telling dotnet not to delete these controls makes it do exactly that. Or maybe it’s Max gc’ing it. I dunno. The randomness of it was so frustrating too. Sometimes it worked, sometimes it didn’t.