Notifications
Clear all

[Closed] dotNet UI

 lo1
try(destroydialog ::rlList)catch()
rollout rlList "" 
( 

	dotNetControl lvObjects "System.Windows.Forms.ListView" width:250 height:150 pos:[10,10]
	dotNetControl btnA "Button" width:125 height:25 pos:[10,160]
	dotNetControl btnB "Button" width:125 height:25 pos:[135,160]

	on rlList open do 
	( 
		-- Setup the listview
		lvObjects.View = (dotNetClass "System.Windows.Forms.View").Details  
		lvObjects.fullRowSelect = true  
		lvObjects.Columns.add ("Objects")
		lvObjects.columns.item[0].width = rlList.width - 24
		
		-- Add items to listview
		for x=1 to 5 do 
		(
			local newItem = dotNetObject "System.Windows.Forms.ListViewItem" ("Col." + x as string)
			lvObjects.items.add newItem    
		)  
	)


		
	on lvObjects ColumnClick e do
	(
		clearlistener()
		for i = 0 to lvObjects.Items.count-1 do lvObjects.Items.item[i].Selected = true
	)
	
	on rlList resized val do (
		w = val[1]
		h = val[2]
		lvObjects.width = (w-20)
		lvObjects.height = (h-40)
		lvObjects.columns.item[0].width = w - 24
		local bWidth = lvObjects.width / 2
		local bPosY = lvObjects.pos[2] + lvObjects.height
		btnA.width = bWidth
		btnB.width = bWidth
		btnA.pos = [btnA.pos[1], bPosY]
		btnB.pos = [btnA.pos[1] + bWidth, bPosY]
	)
)
createDialog rlList 270 190 style:#(#style_SysMenu, #style_ToolWindow, #style_resizing)

This is the long hard way using a max rollout.
Using DotNetObjects would make this as simple as setting a single property.

the real problem is how to avoid showing and flickering of the horizontal scroll bar.

 lo1

This is the only way I know:
http://stackoverflow.com/a/2500089/860585

for WS_HSCROLL the order of messages is different. the same code doesn’t work for the horizontal scroll bar.
actually the code is not absolutely correct but the overriding the WndProc is the only way that I found.

If you don’t mind showing, I’m open to doing it with DotNetObjects. Feel free to show that example. I am not locked on using the max rollout.
I usually just avoid using them because the setup require more work to avoid issues like gc and window parenting.

 lo1

On second thought forget what I said. To do this without handling the resize handler you need a TableLayoutPanel, and that’s a PITA to set up in maxscript.

This seems like a lot when all I’m really after is the ability to have a horizontal scroll and resizeable window.

Downside is that there is no stored Selection focus on the listview. I saw that people change the background color to match the selection highlight to make it appear to not have lost focus.

Another bugger is that I can not multi-line select by click and drag. It wants to select only a single object in the list.

What are your guys thoughts on this?
Ways to improve this or just stick the maxscript dialog?


--Destroy dialog if it already exists.
try(destroyDialog theRollout)catch()

--Create a rollout
rollout theRollout "The Rollout" width:300
(
	--Create the dotNet listview control
	dotNetControl lv "system.windows.forms.listView" pos:[10,40]
	
	--Create a button for testing. 
	button btnDelete "Delete Objects" height:25 width:100 pos:[10,10]
	button btnUpdate "Update" height:25 width:70  pos:[120,10]
	
	fn populateList = (
		lv.items.clear()
		for node in objects as array do 
		(
			item = lv.items.add node.name
			item.tag = dotnetmxsvalue node
		)
	)
	
	fn ListViewReturnSelectedIndexs ListView = (
		local RetArray = #()
		local tnPropColl = getProperty ListView #selectedItems
		
		for Row = 0 to ( tnPropColl.count-1) do
			(
				local tnProp = tnPropColl.get_item Row
				append RetArray tnProp.Index --index up for maxs arrays which start at 1
			)
		RetArray
    )
	
	on btnUpdate pressed do (populateList())
	
	on btnDelete pressed do (
		selIdxs = ListViewReturnSelectedIndexs lv
		_objCol = for i in selIdxs collect (lv.items.item[i].tag.value)
		delete _objCol
		populateList()
	)
	
	--Innitialize the listview control
	fn initLv theLv=
	(
		--Setup the forms view
		theLv.view=(dotNetClass "system.windows.forms.view").details
		theLv.FullRowSelect=true		--Set so full width of listView is selected and not just first column.
		theLv.GridLines=true			--Show lines between the items. 
		theLv.MultiSelect=true			--Allow for multiple selections. 
	)
	
	--Add columns. 
	fn addColumns theLv columnsAr=
	(
		w=(theLv.width/columnsAr.count)-21	--Calculate the width of each column.
		for x in columnsAr do		--Loop through all the column names to be added. 
		(
			theLv.columns.add x w		--Add each new column to the listview control. 
		)
	)

	fn resizeUI = (
		lv.width = (theRollout.width-20)
		lv.height = (theRollout.height-50)
		lv.columns.item[0].width = (lv.width - 21)
	)
	
	on theRollout resized val do (
		resizeUI()
	)
	
	on theRollout open do
	(
		initLv lv
		addColumns lv #("Object")
		populateList()
		resizeUI()
	)
)

--Create a dialog and assign the rollout to it. 
createDialog theRollout 200 200 style:#(#style_SysMenu, #style_ToolWindow, #style_resizing)

1 Reply
 lo1
(@lo1)
Joined: 11 months ago

Posts: 0

I definitely remember a thread that dealt with this problem successfully.

here is how to keep selection after the losing focus:


 		theLv.HideSelection = off
 		theLv.BackColor = (dotnetclass "System.Drawing.SystemColors").Menu
 

The flickering you get with dotNet controls within rollouts is pretty nasty. Personally I much prefer using a form and then using the anchor property to get automatic resizing. This way there is zero flickering and the resize animation is very smooth.

Something like this:





mf = dotNetObject "MaxCustomControls.MaxForm"
lv = dotNetObject "listview"
btn = dotNetObject "button"



mf.size = dotNetObject "System.Drawing.Size" 500 250

btn.size = dotNetObject "System.Drawing.Size" 460 30
btn.location = dotNetObject "System.Drawing.Point" 10 10

lv.size = dotNetObject "System.Drawing.Size" 460 150
lv.location = dotNetObject "System.Drawing.Point" 10 50
lv.view=(dotNetClass "system.windows.forms.view").details
lv.columns.add "Column 1" (mf.width-200)

anchorStyle = (dotNetClass "System.Windows.Forms.AnchorStyles")
btn.anchor = dotnet.combineEnums anchorStyle.top anchorStyle.left anchorStyle.right
lv.anchor = dotnet.combineEnums anchorStyle.top anchorStyle.bottom anchorStyle.left anchorStyle.right


mf.controls.add btn
mf.controls.add lv


mf.show()


function resizeColumn = lv.columns.item[0].width = mf.width-200
dotNet.addEventHandler mf "Resize" resizeColumn


here is a template that shows how to make this kind of UI (rollout, resizable LV, docked on top Buttons, one Button with fixed size):


 try(destroyDialog resizeRollout) catch()
 rollout resizeRollout "The Rollout" width:200
 (
 	dotNetControl panel "Panel" width:0 height:0 pos:[2,2]
 	
 	local lv, delete_bt, update_bt
 	fn makeUI =
 	(
 		panel.Backcolor = ((dotnetClass "ManagedServices.CuiUpdater").GetInstance()).getMaxColor 0 
 		
 		lv = dotnetobject "ListView"
 		lv.Dock = lv.Dock.Fill
 		lv.View = lv.View.Details
 		lv.FullRowSelect = lv.GridLines = lv.MultiSelect = on
 		lv.HideSelection = off
 		lv.BackColor = (dotnetclass "System.Drawing.SystemColors").Menu
 		lv.Columns.Add "Name"
 		items = for k=0 to 11 collect (dotnetobject "ListViewItem" ("Node " + k as string))
 		lv.Items.AddRange items
 			
 		fn onClientSizeChanged s e =
 		(
 			s.Columns.Item[0].Width = s.ClientSize.Width-1
 		)
 		dotnet.addEventHandler lv "ClientSizeChanged" onClientSizeChanged
 		
 		pn = dotnetobject "Panel"
 		pn.Backcolor = pn.Backcolor.Transparent
 		pn.Height = 24
 		pn.Dock = pn.Dock.Top
 
 		bt = dotnetobject "Button"
 		bt.Backcolor = bt.Backcolor.Transparent
 		bt.Text = "Delete"
 		bt.Height = 24
 		bt.Dock = bt.Dock.Fill
 		delete_bt = bt
 
 		bt = dotnetobject "Button"
 		bt.Backcolor = bt.Backcolor.Transparent
 		bt.Text = "Update"
 		bt.Height = 24
 		bt.Width = 60
 		bt.Dock = bt.Dock.Right
 		update_bt = bt
 		
 		pn.Controls.AddRange #(delete_bt, update_bt)
 		panel.Controls.AddRange #(lv, pn)
 	)
 	fn resizeUI size: = 
 	(
 		if size == unsupplied do size = getdialogsize resizeRollout
 		panel.width = size.x-4
 		panel.height = size.y-4
 	)
 	
 	on resizeRollout resized val do resizeUI()
 	
 	on resizeRollout open do
 	(
 		makeUI()
 		resizeUI()
 	)
 )
 createDialog resizeRollout 200 200 style:#(#style_SysMenu, #style_ToolWindow, #style_resizing)
 
Page 13 / 18