DotNet NumericUpDown Control


I’m using NumericUpDown controls in my Max tools as a replacement for spinners. I’ve even got the click and drag functionality working for quickly changing the value.

But there’s one thing that bugs me. Querying the .value property of the control always returns an integer, even if it’s set up with multiple decimal places and a fractional increment. The problem is that the value type is a Decimal, which is converted to Integer in Max. Why, I don’t know. But in order to get the same value displayed in the control, I have to use <control>.Text as float.

Getting the text and converting to a float seems messy and adds unnecessary overhead to using this type of control. Has anyone else been using these and found a way around having to do the extra conversion? Or is it possible to create a custom control based on the NumericUpDown that returns a float instead of the decimal?


why not create a new .NET float value, feeding it the value from the updown control, and then let maxscript cast that to its own float?

Edit: riiight… because maxscript converts it first before it gets passed to .NET. mutter


Yeah, that’s exactly my point. Any reason you can think of that they wouldn’t convert decimals to floats instead of integers?


nope… considering decimal -is- a float type (just represented in decimal space rather than binary).

I’m not seeing some obvious clean work-around either (could’ve sworn there was one, but that was getting maxscript values into the type .NET wants, not the other way around). Setting the number of decimal points to something silly (if required), grabbing the text, converting to float, restoring decimal points (if required) seems to be it.


Hi James, Hope you are well.

because they dont want to! It's a max problem!

in the topic MAXScript / DotNet Value Conversions

       [left]DotNet  type : Byte, SByte, Decimal,  Int16, UInt16, Int32, UInt32          

converts to

MAXScript type :Integer[/left]

So as you correctly pointed out, the numeric updown returns a decimal, which is cast to an integer in MXS. why this has been done like that is a mystery to me. 

One solution is to build an user control that inherits the numericupdown, but overides the valuechanged event handler and replaces it with a custom event handler - in this case something that returns the spinner's value as a single. That way, max will cast it to a float. 

Here's something i knocked up quickly in VB, it's far from the finishised item, but you get the idea. If you were really desparate, I could be persuaded to work on it a bit more if it's what you need! :cool: just bung the assembly in a directory and load it from there.
dotnet.loadassembly ((getdir#scripts)+"\LoneRobot\ClassLib\Floatspinner")
    rollout FS "" width:162 height:36
    	dotNetControl num "Lonerobot.ui.floatspinner" pos:[6,5] width:150 height:25	
    	on num valuechanged sender args do print args.value 	
    createdialog FS

there’s a precision property that will set the decimal places and the increment to the correct number, ie precision = 3 sets places to 3 and increment to 0.001.

edit: Control has now been updated, downnload from the link below!


Thanks Pete. I’ll take a look at that.

Also note that the maximum, minimum, and increment values are also decimals. So you can set them using a float but they always return as integers. Very annoying.

I’m trying to get up to speed in C# as I get time, and I’d love to take a stab at creating my own custom version of the control that more closely mimics the behavior of Max spinners, like click and drag, right-click to exit, and right-click to zero out the value. I have all of that working in script using various event handlers and a rollout timer, but it would be nice to have it all packaged in the control itself.


im wondering whether autodeska re already on the case. when i was looking at the max managed services dll in visual studio, I saw a reference to a maxspinner class. I can instantiate it in max but get errors when i try to use it on a rollout or form. The encouraging thing is this -

so im not sure if it is working or not, i cant load it into a project in VS either. I’ll post at the area on the SDK blog and see if i can clear it up.


Good find. I’d be interested in hearing what you find out.


Pete, a question regarding your control.

Is there any way to get the float value from the spinner when you’re not asking it from a change handler? (where you don’t have access to the args variable)


Hi Dubbie,

Sure, you just use the value property to get this info from the control at any time.


It seems to return an Int when I do that.


my apologies, as james mentioned before, there are a few properties that return a decimal that need to be overridden and converted into a single so that max doesnt do the integer conversion.

I’ve updated the control so it should now return a float in max by using value,minimum,maximum and increment.

(click the image to download)

I have also added right click to reset functionality too.


Thanks Pete!

Very useful!


Hi all,

Further to some feedback to the control i’ve added it to my blogas a tutorial. It also includes the source code so that you can pick apart building a custom control for max. I was thinking I might write a tutorial series on writing custom controls for max if it would be useful.


About the conversion problem with the NumericUpDown control, I have found the way to get over it.
Using getProperty <dotNetObject> <prop name> [asDotNetObject:<bool>] to get the decimal value without MAXScript conversion and using Decimal.ToSingle().
See on btnGetValue MouseClick event handler :

 	rollout upDownRolloutTest "NumericUpDown Control Test" width:220 height:45
 		dotNetControl upDownCtrl "System.Windows.Forms.NumericUpDown" pos:[10,10] width:50 height:25
 		dotNetControl btnGetValue "System.Windows.Forms.Button" pos:[90,10] width:100 height:21
 		on upDownRolloutTest open do
 			upDownCtrl.DecimalPlaces = 1
 			upDownCtrl.Increment = 0.1
 			upDownCtrl.Value = 1.0
 			upDownCtrl.Minimum = 0.0
 			upDownCtrl.Maximum = 10.0
 			btnGetValue.Text = "Get Value"
 			btnGetValue.FlatStyle = (dotNetClass "System.Windows.Forms.FlatStyle").System
 		on btnGetValue MouseClick do
 			-- Get the value auto converted by MAXScript
 			fValue = upDownCtrl.Value
 			format "Wrong Value : %
" fValue
 			-- Get the decimal value as a .NET object
 			dValue = getProperty upDownCtrl #value asDotNetObject:true
 			-- Convert it to single object value then auto converted to float value by MAXScript
 			fValue = (dotNetClass "System.Decimal").ToSingle dValue
 			format "Good Value : %
" fValue
 	createDialog upDownRolloutTest


great solution, yannick! :thumbsup:


Nice solution, thanks for that.


Thanks for the workaround yannick.


I’ve added your solution to my blog entry Yannick, hope that is okay. cheers!


No problem Pete. Thanks also for the info about MaxSpinner wrapper in Managed Services assembly.