dotNet + MXS


or the modern technique :slight_smile:

source += "		public void MoveNode(DevExpress.XtraTreeList.TreeList tv, DevExpress.XtraTreeList.Nodes.TreeListNode source, dynamic target)
source += "		{
source += "			tv.MoveNode(source, target);
source += "		}


am new for dot net but trying to discover its possibilities
i wonder how i can rich to max tools and windows from dot net ?
is it possible to change its properties "like docking for example "?


Hi. Is it possible to add multiple menuItems to contextMenu or multiple dropdown items at one time. Like in my case i have an array of names, which need to be added to contextmenu. I wonder how to do it as a single coommand.

	cm = dotnetobject "ContextMenu"
	list = #("a","b")
	for item in list do cm.MenuItems.Add item
-- or
	cm.MenuItems.AddRange (for item in list collect (dotnetobject "MenuItem" item))


Thank you for your reply DenisT.

Another problem i’ve tried to resolve but without luck was this:

I have some material library, and via dotnet contextMenustrip i’m making a dropdown contextmenu. The problem is with click event. It must assign material with the same name as DropDownItem has. But the MatMenu variable contains the last item, which was added in loop. How can it be done? I mean the click event for each subMenu item.

Thank you.

	mat = #some material library

	cursor = dotNetClass "System.Windows.Forms.Cursor"
	MMenu = dotNetObject "System.Windows.Forms.ContextMenuStrip"

	for i = 1 to mat.count do
		LibMenu = dotNetObject "System.Windows.Forms.ToolStripMenuItem"  (mat[i].name as string)
		LibMenu.tag = i
		MMenu.Items.Add LibMenu
		for j = 1 to mat[i].count where (mat[i][j] != undefined)  do
			MatMenu = dotNetObject "System.Windows.Forms.ToolStripMenuItem" (mat[i][j].name as string)
			MatMenu.tag = j
			LibMenu.DropDownItems.Add MatMenu
			dotnet.addeventhandler matMenu "Click" GiveMat 


				fn giveMat  = 
				$.material = mat[libMenu.tag][matMenu.tag]
			) cursor.position

// Updated:
I’ve made it work so far. The code is below

mat = #some material library
for i = 1 to mat.count do
		LibMenu = dotNetObject "System.Windows.Forms.ToolStripMenuItem"  (mat[i].name as string)
		MMenu.Items.Add LibMenu
		for j = 1 to mat[i].count where (mat[i][j] != undefined)  do
			MatMenu = dotNetObject "System.Windows.Forms.ToolStripMenuItem" (mat[i][j].name as string)
			MatMenu.tag = #(i,j)
			LibMenu.DropDownItems.Add MatMenu
			dotnet.addeventhandler matMenu "Click" GiveMat 
			dotNet.setLifeTimeControl MatMenu #dotNet			
		dotNet.setLifeTimeControl LibMenu #dotNet

		fn giveMat sender arg  = 
				a = sender.tag[1]
				b = sender.tag[2]
				$.material = mat[a][b]


instead of putting indexes of material and sub material to tag you can put an actual material

menuitem.tag = dotnetmxsvalue mat -- where mat is a material


When having DevXpress.XTraTreeList inside Container, the cell editor is not getting all keys when typing. It “fights” with 3dsmax shortcuts! Any idea how to focus typing keys to editor, please?

(I have more XtraTreeLists inside container , not in this example.)

 rollout tester "TESTER" (
	dotnetcontrol myCont "MaxCustomControls.MaxUserControl" width:300 height:200 
	local dxt = dotNetObject "DevExpress.XtraTreeList.TreeList"
	on tester open do (
		srcSC1 = dotnetobject "SplitContainer"
		srcSC1.dock = srcSC1.dock.fill
		srcSC1.Panel1.controls.add dxt
		myCont.controls.add srcSC1
		col.visible = true
		col.Caption = "Column"
		n = dxt.AppendNode #("Text") -1
createDialog tester 350 250


search on this forum for enableAccelerators


Aaahh, yes … accelerators… I knew I saw this issue already… I just could name it… Thanks a lot, Denis!


If I would like to force MAX to load/substitute another version of devexpress libraries, what would be the necessary steps to achieve that? Any idea, please?


if they are .DLL files, you can use mxs

dotnet.loadassembly @"c:\path	o\my.dll"


Thanks mate, but imho it won’t be so easy this time. I have suspicion that some wrapper must be involved in this case. I’m looking more less for substitution of current library with new one from newer version of MAX to achieve compatibility of the tool.



I’ve recently started dabbling in writing some functions in dotnet using Autodesk.max.dll in 2015.

My functions work fine, but I’m puzzled on how to supply the node to the fucntion from maxscript.

I’ve worked around it by being able to pass the node handle into the dotnet function, then using GetINodeByHandle to get hold of it.

I’d rather just be bale to pass the node itself, rather than its handle.
Does anyone know how to do this please?



Hi there,

I’m trying to write a script that associates data polled from a Socrata open-data platform to geometry in my model.

I’m using this C# library:

With this dataset:

I have successfully loaded the library in maxscript and set up a client object. But when I call the client.getResource method I get this error: "Runtime error: dotNet runtime exception: Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.”

I gathered that getResource returns a generic type, but I can’t figure out how to cast that type into something maxscript understands.

Does anyone know how work with generic types or how to cast a variable type in maxscript?



دکوراسیون داخلی
thank you.


edit: wrong post.


Just don’t try to program c# using max script. you have very limited capabilities there. It is best to simply write a plugin to do what you need and then expose some functionality back to max script.


I have same problem , now i use vs to create an user control contains a devexpress treelist control, complie it to a dll file , use mxs to call it ,it work fine, maybe you can try this.


This thread has been invaluable for me to learn. But I’m having trouble with checkboxes and selecting them in the UI and checking and unchecking them.

This is a snippet of code below I want to control the checkboxes by multiple selections and hitting the checkbox (whether checked or not) to select / de-select them accordingly, trouble is when I do this it doesn’t do them in one go but for each item. And you can visually see the text count up or down of the countLabelVal text.

What would the best way of displaying the checked count of the listview while overcoming the problem above?

try(destroydialog ::lvRolTest)catch()
rollout lvRolTest "Check Mate.."

  local lvSetItemsProp
  local resizeListView

  label         countLabelPrefix  "How many you say ?" across:3
  label         countLabelVal     ""
  checkButton   chkLvButton       "Un/check All..."
  dotNetControl lv                "ListView" width:250 height:545 pos:[10,30]

  on lvRolTest open do
    lv.View             = (dotNetClass "View").Details
    lv.FullRowSelect    = true
    lv.GridLines        = true
    lv.MultiSelect      = true
    lv.Checkboxes       = true
    lv.Columns.add      ("Items")


    for x=1 to 100 do
      local newLvItem = dotNetObject "ListViewItem" ("Item " + x as string)
      newLvItem.checked = true
      lv.items.add newLvItem
    countLabelVal.text = (lv.CheckedItems.count) as string

  on lvRolTest resized val do (

  on chkLvButton changed state do (
   if state do chkLvButton.text         = "Check All..."
   lvSetItemsProp rolArg:(#lvRolTest as string) lsArg:(#lv as string) prop:#Checked state:((not state) as string)
   if not state do chkLvButton.text     = "Uncheck All..."
   countLabelVal.text = (lv.CheckedItems.count) as string

  on lv ItemChecked do
    if lv.CanSelect and lv.CanFocus and lv.Focused then
      countLabelVal.text = (lv.CheckedItems.count) as string

  fn resizeListView = (
    lv.width                 = lvRolTest.width-20
    lv.height                = lvRolTest.height-40
    lv.columns.item[0].width = lvRolTest.width-40.5

  fn lvSetItemsProp rolArg:#rolArg lsArg:#lsArg prop:#checked state:#false = (
    execute("for i = 0 to "+rolArg+"."+lsArg+".items.count-1 do "+rolArg+"."+lsArg+".items.item[i]."+prop+"="+state)

createDialog lvRolTest 270 575 style:#(#style_SysMenu, #style_ToolWindow, #style_resizing)


I have a dll (ClmListener) that processes facial position data via a websocket on my web site .It has a method called ‘frame’, triggered by Onframe,

which sends out the data. I am using the following mxs in an attempt to print out position values as a test.
After starting the console…

   <            dotnet.loadAssembly "C:\\Release\ClmListener.dll"

struct ClmTracker
IpAddress = "",
Port = 8087,
Interval = 1000,
ClmListener = dotNetObject "Clm.Listener",
VideoResolution = dotNetObject "Clm.Points2d",
MainThread = dotnetobject "CSharpUtilities.SynchronizingBackgroundWorker",

fn Start =
	-- if MainThread.IsBusy do MainThread.CancelAsync()
	--if not MainThread.IsBusy do MainThread.RunWorkerAsync()

fn StartAsync =
	while true do
		task = ClmListener.Start IpAddress Port Interval
	-- ClmListener.Stop()

fn onSetResolution resolution =
	VideoResolution = resolution

fn onFrame  = 
        print "hey"
		print "#: " +  frame.Number
		print "Timestamp: " + frame.Timestamp
		for	point in frame.Points do print "[" + point.X + ", " + point.Y + "]"

	print frame.ToString

fn init =
	--dotNet.addEventHandler ClmListener "OnSetResolution" onSetResolution
	dotNet.addEventHandler ClmListener "onframe" onFrame;

	MainThread.WorkerSupportsCancellation = true
	MainThread.WorkerReportsProgress = true
	dotNet.addEventHandler MainThread "DoWork" StartAsync

initialized = init()

  --clmTracker = ClmTracker()

/ >
However it is not printing any data and states that clmtracker,Start() is undefined, although it accepts the onframe event handler, and the listener console prints out the data…
This is puzzling as it has previously done so. Any idea? I attach the sln file for the dll…

      <a class="attachment" href="/uploads/default/original/3X/2/9/">ClmListener.Console(5).zip</a> (16.6 MB)

Here is the console app:
Console.App(3).zip (651.0 KB)

Dot NET and sending data to max from websocket