Notifications
Clear all

[Closed] dotnet.addEventHandler and structs

 e-x

Trying to access a struct’s member by way of a dotnet button using dotnet.addEventHandler, but I’m running into an exception trying to access it’s value:

–Runtime Error: Struct member access requires instance: storedNodes

Here’s my test code:

clearListener()
try (destroydialog testRollout ) catch()
   
rollout testRollout "testRollout" width:664 height:60
(		   
	struct charData 
	(
		b = dotnetobject "button",		
		storedNodes,
	   		
		fn printAry sender arg =
		(
			print storedNodes
		),
				
		on create do
		(		
			dotnet.addEventHandler b "mouseDown" printAry
		)
	)
	
   	fn AddFlowLayoutNodes control =
   	(		
   		for i = 1 to 6 do
   		(
			p = dotnetobject "flowlayoutpanel"
			p.size = (dotNetObject "System.Drawing.Size" 100 40)
			p.backcolor = (dotnetclass "system.drawing.color").DarkGray
			control.Controls.add p
			
			newLimb = charData storedNodes:i
			print newLimb.storedNodes
			newLimb.b.text = ("Button: " + (i as string))
			
			p.controls.add newLimb.b
			
			if i == 6 do (return p)
   		)	
   	)	
   	
   	dotNetControl flp "system.windows.forms.flowlayoutpanel" pos:[2,4] width:654 height:50
   
   	on testRollout open do
   	(
		flp.borderstyle=  (dotNetClass "system.windows.forms.borderstyle").fixedsingle	
		flp.autoscroll = true
		
		flp.SuspendLayout()		
		flp.setflowbreak (AddFlowLayoutNodes flp) true			
		flp.resumelayout()
	)
)

createdialog testRollout

I did find this thread, but I still don’t understand what’s going on. Any help would be greatly appreciated, thank you.

10 Replies
1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

you code is almost correct, i just made a little modification to make it work:


try (destroydialog testRollout ) catch()
   
rollout testRollout "testRollout" width:664 height:60
(		   
	struct charData 
	(
		b = dotnetobject "button",		
		storedNodes,
			   
		fn printAry sender arg =
		(
			print sender.tag.value.storedNodes
		),
				
		on create do
		(		
			b.tag = dotnetmxsvalue this
			dotnet.addEventHandler b "mouseDown" printAry
		)
	)
	
	   fn AddFlowLayoutNodes control =
	   (		
		   for i = 1 to 6 do
		   (
			p = dotnetobject "flowlayoutpanel"
			p.size = dotnetobject "System.Drawing.Size" 100 40
			p.backcolor = p.backcolor.DarkGray
			control.Controls.add p
			
			newLimb = charData storedNodes:i
			print newLimb.storedNodes
			newLimb.b.text = ("Button: " + (i as string))
			
			p.controls.add newLimb.b
			
			if i == 6 do (return p)
		   )	
	   )	
	   
	   dotNetControl flp "flowlayoutpanel" pos:[2,4] width:654 height:50
   
	   on testRollout open do
	   (
		flp.borderstyle =  flp.borderstyle.fixedsingle	
		flp.autoscroll = true
		
		flp.SuspendLayout()		
		flp.setflowbreak (AddFlowLayoutNodes flp) true			
		flp.resumelayout()
	)
)

createdialog testRollout

the event function defined in structure before the structure created. so it knows nothing about the members. using button’s tag i pass the instance of the structure to the event function…

If you’re using a dotnetcontrol in a maxscript rollout it might save a lot of trouble to use the “standard” maxscript way of catching events. E.g. :

on b MouseDown s e do .....

You can catch any .net control event this way.

 e-x

I’ve done that before for other things, but in this case I’m trying to build a UI within a struct, including a listview and buttons to add and delete objects out of it.

You can’t create a dotNetControl inside of a struct, correct? The code I posted seems like it should work.

Aha sorry I missed that struct. I think this kind of construct is a little odd…having a struct inside a rollout. Why would you want to do that?

 e-x

I’m using a struct to build UI elements, a listview and some buttons, and then dynamically add them all to a flowlayoutpanel.

I’m open to suggestions if anyone has a better way.

1 Reply
(@panayot)
Joined: 11 months ago

Posts: 0

Just quick guess but looks like a variable scope issue.
You made struct instance inside AddFlowLayoutNodes()
but is that instance is visible outside the function?

here is a little more elegant way how to define the structure above:


	struct charData 
	(
		storedNodes,
		b = 
		(
			local printAry
			fn printAry sender arg =
			(
				print sender.tag.value.storedNodes
			)
			b = dotnetobject "Button"
			dotnet.addEventHandler b "MouseDown" printAry
			b
		),		
		on create do
		(		
			b.tag = dotnetmxsvalue this
		)
	)


2 Replies
(@jsnb)
Joined: 11 months ago

Posts: 0

Hi Denis,

Why do you forward declare the printAry function name?

J.

(@denist)
Joined: 11 months ago

Posts: 0

it’s one of my finds how to trick the script compiler… try to evaluate the same code without the declaration.

 e-x

Works like a charm, thanks Denis.