Notifications
Clear all

[Closed] dotnet listview look / feel like MultiListBox ?

I’ve been playing around with the dotnet listview trying to make it look / feel like a MultiListBox control.
The style i’m using is System.Windows.Forms.View.List
The immediate differences are:
1. Even with ‘fullRowSelect’ on, it doesn’t really select a full row – only to the extent of the text.
2. I don’t need to be able to marquee select items yet still be able to click + drag select.
3. the MultiListBox has a black outLine around it which is not a big deal but would be nice to know
If you’re not sure about what I mean, check out the differences in this example code:

(
     	global lvTestRollout
     	try(destroyDialog lvTestRollout)catch()
     	rollout lvTestRollout "lvTestRollout"
     	(
     		local ListItems = #("These are some items", "for the example of", "the ListViews", "vs", "the MultiListBox")
     		
     		dotNetControl lv "System.Windows.Forms.ListView" height:150
     		multiListBox lb "MultiListBox" height:10
     		
     		fn initListView =
     		(
     			lv.backColor = (dotNetClass "System.Drawing.Color").FromArgb 225 225 225
     			--The following controls the display of details. We use defaults:
     			lv.gridLines = true
     			lv.View = lv.View.List
     			lv.fullRowSelect = true
     			lv.hideSelection = false -- show selected objects when listview is not in focus
     		)
     		
     		fn fillInListView =
     		(
     			theRange = for i in ListItems collect dotNetObject "System.Windows.Forms.ListViewItem" i
     			lv.Items.AddRange theRange
     		)
     		
     		on lvTestRollout open do
     		(
     			initListView()
     			fillInListView()
     			lb.items = listItems
     		)
     	)
     	createDialog lvTestRollout width:400 height:320
     )

EDIT: ok so i’ve answered the first 2 questions a few mins after posting…
It’s not 100% the same but close enough. It seems I need to use System.Windows.Forms.View.Details and add a column for fullRowSelect to work properly which also seemed to solve number 2. Even though you use a marquee selection, it behaves pretty much like the MulitListBox. I’d still prefer not to use the marquee if anyone knows of a way around it but it but as I said it’s close enough for now. Also I still havn’t figured out problem 3…

27 Replies

Hello Joel,

you’ve answered most of your own question already. But this is what i came up with:

lv.View = lv.View.details
 lv.columns.add "" --add a column to be able to see the items
 lv.columns.item[0].width = lv.width
 lv.headerStyle = lv.headerStyle.none --hide the columnheader
 lv.borderStyle = lv.borderStyle.none --no border around the control
 --lv.borderStyle = lv.borderStyle.fixed3d --default border around the control
 --lv.borderStyle = lv.borderStyle.fixedSingle--a single black line around the control

In your example i don’t see a black outline around the multilistbox. The two example-controls look very much alike on my machine. I wouldn’t know how NOT to get the marquee.

Hope it helps,

Klaas

thanks for the headerstyle tip, works great. I’ve made some headway with this since posting. I’ve now got a custom colored selection that remains visible when focus is lost as well as drag / ctrl+drag select / deselect that works like a MultiListBox. Still havn’t gotton rid of that marquee though…

Here’s the updated code if anyone’s interested:

(
	global lvTestRollout
	try(destroyDialog lvTestRollout)catch()
	rollout lvTestRollout "lvTestRollout"
	(
		local ListItems = #("These are some items", "for the example of", "the ListViews", "vs", "the MultiListBox")
		local hitNode
		local selMode
		local selModeActive = false
		
		local selColor = (dotNetClass "System.Drawing.Color").fromARGB 238 204 85 -- custom selection color (orangey-yellow)
		local lvBackColor = selColor.fromARGB 225 225 225
		
		dotNetControl lv "System.Windows.Forms.ListView" height:150
		multiListBox lb "MultiListBox" height:10
		
		fn initListView =
		(
			lv.backColor = lvBackColor
			lv.Columns.add "XRef Files:" (lv.width-4)
			lv.headerStyle = lv.headerStyle.none --hide the columnheader
			lv.Sorting = lv.Sorting.None
			lv.View = lv.View.Details
			lv.fullRowSelect = true
			lv.ownerdraw = true
		)
		
		fn fillInListView =
		(
			theRange = #()
			for i = 1 to 2 do join theRange ( for i in ListItems collect dotNetObject "System.Windows.Forms.ListViewItem" i )
			lv.Items.AddRange theRange
		)
		
		on lv MouseDown arg do if (hitNode = lv.GetItemAt arg.x arg.y) != undefined do
		(
			if keyBoard.controlPressed then selMode = NOT hitNode.selected
			else
			(
				for i = 1 to lv.SelectedItems.count do lv.SelectedItems.Item[0].selected = false -- clear the selection
				selMode = true
			)
			hitNode.selected = selMode
			selModeActive = true
		)
		
		on lv MouseMove arg do if selModeActive do
		(
			hitNode = lv.GetItemAt arg.x arg.y
			if hitNode != undefined do hitNode.selected = selMode
		)
		
		on lv MouseUp arg do
		(
			selModeActive = false
			if hitNode != undefined do hitNode.selected = selMode
		)
		
		on lv ItemSelectionChanged arg do
		(
			arg.Item.BackColor = if arg.isSelected then selColor else lvBackColor
		)
		
		on lv drawitem arg do
		(
			arg.DrawBackground()
			arg.DrawText()
		)
		
		on lvTestRollout open do
		(
			initListView()
			fillInListView()
			lb.items = listItems
		)
	)
	createDialog lvTestRollout width:400 height:320
)
 JHN

Gravey, this is good stuff, some bits I needed badly thanx!

-Johan

hi joel,

the dotnet listbox control has a SelectionMode.MultiExtended or a SelectionMode.MultiSimple property that gives it a similar feel to a max multilistbox. I didn’t know if that was something you’d already looked at and dismissed in favour of the listview.

	try(destroyDialog lvTestRollout)catch()
 	rollout lvTestRollout "lvTestRollout"
 	(
 		local ListItems = #("These are some items", "for the example of", "the ListViews", "vs", "the MultiListBox")
 		local hitNode
 		local selMode
 		local selModeActive = false
 		
 		local selColor = (dotNetClass "System.Drawing.Color").fromARGB 238 204 85 -- custom selection color (orangey-yellow)
 		local lvBackColor = (dotNetClass "System.Drawing.Color").fromARGB 225 225 225
 		
 		dotNetControl lv "System.Windows.Forms.Listbox" height:150
 		multiListBox lb "MultiListBox" height:10
 			
 		on lvTestRollout open do
 		(
 			lv.backcolor = lvbackcolor
 			lv.SelectionMode =(dotnetclass "System.Windows.Forms.SelectionMode").MultiExtended
 			lv.items.addrange listitems
 			lb.items = listItems
 		)
 	)
 	createDialog lvTestRollout width:400 height:320
 )

Hey Pete,

Thanks for the dotnet listbox info – I hadn’t considered it.
In this case I’d prefer a custom selection color as well. If you know a way of doing that with the listbox that’d be great, otherwise i’ll stick with the listview.

cheers

 PEN

With the listView control I have just changed the background colour of the selected object in the list. Not sure that you can directly set the colour of the selection.

Hi Joel,

I think this would be possible, if not in max then with an inherited listbox control. I will have a ferret around and see if i can work it out.

Hi Joel,

I think i’ve figured it out. I tried converting the VB code into something max could pallette, but it kept spitting it back at me. It was rejecting a method i was using in visual studio as being not relevant, but that’s probably because i was doing it wrong. In the end I wrote a small inherited control that does does the drawing of the selected node itself. It has a couple of extra properties in there too. Firstly, there is a selecteditemcolor property for the selected background, and also a selecteditemtextcolor property too, in case you need to invert the text or something. If you dont, just set it to the foreground color. here it is –

[left]click the image to download it. there is the MXscript file in the zip too. hope this is what you needed.
[/left]

Paul: Thanks and check the last bit of code that I posted – I’ve already got it working.

Pete: Thanks heaps, your custom control works great. I wish I knew C# so I could do this kind of thing myself. 
I just read through my previous posts and it seems i forgot to mention something... I also needed individual control over the ForeColor of items, whether they are selected or not. Again, this is where I wish i knew C#... Can you suggest any good resources to get started in C# ? 
Either way I wont trouble you for the ForeColor part, I'm not sure if it'd be so 'easy' with the ListBox since its Items are just strings and not 'ListItem' objects with their own properties. The ListView will be fine - and we've now got a great custom ListBox control too! Thanks again for that.
Page 1 / 3