[Closed] dotNet listview like multilistbox
I’m trying to re-create the funtionality created for the multilistbox for the dotnet listbox.
I’m having some issues with the port from one to the other.
- How to properly removed the selected items in the list when the user his ‘-’.
- How to maintain the selecting highlight color when focus is lost.
try(destroyDialog ::rlD)catch()
rollout rlD ""
(
local AnimObjs = #()
local activeFont = dotNetObject "System.Drawing.Font" "Microsoft Sans Serif" 10 (dotNetClass "System.Drawing.FontStyle").Regular (dotNetClass "System.Drawing.GraphicsUnit").Pixel
local mouseIsDown = off
fn fnAddItmsLst lst arr = ( -- add Objects to list
userSel = getCurrentSelection()
if userSel.count >= 1 do
(
for o in userSel do (appendIfUnique arr o)
lst.items = for i in arr collect i.name -- update list with array
)
)
fn fnRemoveItmsLst lst arr = ( -- remove objects from list
local currSel = lst.selection
for i = lst.items.count to 1 by -1 where currSel[i] do (deleteItem arr i)
lst.items = for i in arr collect i.name -- update list with array
lst.selection = #{}
)
fn fnClearLst lst arr = ( -- clears list
for i = lst.items.count to 1 by -1 do (deleteItem arr i)
lst.items = for i in arr collect i.name -- update list with array
lst.selection = #{}
)
--DOT NET CONTROLS--------------------------------
fn fnListviewFactory lv = (
lv.view = (dotNetClass "System.Windows.Forms.view").details
lv.Gridlines = true
lv.Multiselect = true
lv.fullrowselect = true
lv.HeaderStyle=lv.HeaderStyle.Nonclickable
lv.HeaderStyle.Nonclickable
slv.addColumns lv #("Name") #(120)
)
fn fnAddListItems lv arr = ( -- add Objects to list
curSel = getCurrentSelection()
if curSel.count >= 1 do
(
for o in curSel do (appendIfUnique arr o)
rows=#()
for i = 1 to arr.count do (
li = dotNetObject "System.Windows.Forms.ListViewItem" arr[i].name
li.Font = activeFont
append rows li --Added the listViewItem to the rows array
)
--clear listview before re-populating
if lv.items.count > 0 then lv.EnsureVisible 0
for idx = lv.items.count-1 to 0 by -1 do lv.items.removeat(idx)
lv.items.addRange rows
)
)
fn fnRemoveItems lv arr = (
-- idxArr = lv.selectedIndices.Item[0]
-- print idxArr
)
multiListBox lbxAnimatedObjects "Animated Objects" pos:[10,7] width:120 height:12
dotNetControl lvObjectList "Listview" pos:[140, 10] width:150 height:175
button btnAddAnimObj "+" pos:[60,200] width:30 height:30
button btnRemoveAnimObjs "-" pos:[90,200] width:30 height:30
button btnClearAnimObjs "X" pos:[120,200] width:30 height:30
on lvObjectList mouseDown s a do mouseIsDown = on
on lvObjectList mouseUp s a do mouseIsDown = off
on lvObjectList mouseMove s a do if mouseIsDown and (local item = s.GetItemAt a.x a.y) != undefined do item.selected = on
on lvObjectList MouseDoubleClick s a do
(
itm = s.GetItemAt a.x a.y
if itm != undefined do
(
print itm.text
)
)
on lbxAnimatedObjects rightclick do lbxAnimatedObjects.selection = #{}
on btnAddAnimObj pressed do (
fnAddItmsLst lbxAnimatedObjects AnimObjs
fnAddListItems lvObjectList AnimObjs
)
on btnRemoveAnimObjs pressed do (
fnRemoveItmsLst lbxAnimatedObjects AnimObjs
fnRemoveItems lvObjectList AnimObjs
)
on btnClearAnimObjs pressed do fnClearLst lbxAnimatedObjects AnimObjs
on rlD open do (fnListviewFactory lvObjectList)
)
createDialog rlD 300 250 style:#(#style_SysMenu, #style_ToolWindow)
For #2:
This might be overkill – but I had to override the draw method. You can mostly likely find this or similar info in the dotnet thread – it helped me a lot.
When creating your listview turn ownerdraw on:
lv.OwnerDraw = true -- allows for customization of the list
Now in your UI rollout you need to add a drawitem function:
on lv drawitem arg do
(
-- set the background of each line
local selColor = (dotNetClass "System.Drawing.Color").fromARGB 51 153 255 -- a blue default color
local lvBackColor = selColor.fromARGB 225 225 225
arg.Item.BackColor = if arg.Item.Selected then selColor else lvBackColor
arg.DrawBackground()
-- set the foreground of each line
local brush =
(
local brushes = dotNetClass "System.Drawing.Brushes"
case arg.Item.Selected of
(
true: brushes.white
false: brushes.black
)
)
)
*edited for readability
For #1:
Try this
fn AddRangeFn lvObject mxsArr = for i in 1 to mxsArr.count do lvObject.Items.Add (dotNetObject "System.String" mxsArr[i])
fn removeItem arg =
(
if if lvObjectList.items.count != 0 and arg.KeyValue == 109 do --or arg.KeyCode.ToString() == "Substract"
(
lv_selIdx = (for i = 1 to lvObjectList.SelectedItems.Count collect lvObjectList.SelectedIndices.item[i-1]+1)
lv_Items = for i in 1 to lvObjectList.Items.Count collect lvObjectList.Items.item[i-1]
for i = lv_selIdx.count to 1 by -1 do deleteitem lv_Items lv_selIdx[i]
lvObjectList.BeginUpdate()
lvObjectList.items.Clear()
AddRangeFn lvObjectList lv_Items
lvObjectList.EndUpdate()
)
)
dotnet.AddEventHandler lvObjectList "KeyUp" removeItem
added the remove function
Still not solved the keep ‘highlighted selection’ or the remove items in list yet.
try(destroyDialog ::rlD)catch()
rollout rlD ""
(
local AnimObjs = #()
local activeFont = dotNetObject "System.Drawing.Font" "Microsoft Sans Serif" 10 (dotNetClass "System.Drawing.FontStyle").Regular (dotNetClass "System.Drawing.GraphicsUnit").Pixel
local mouseIsDown = off
fn fnAddItmsLst lst arr = ( -- add Objects to list
userSel = getCurrentSelection()
if userSel.count >= 1 do
(
for o in userSel do (appendIfUnique arr o)
lst.items = for i in arr collect i.name -- update list with array
)
)
fn fnRemoveItmsLst lst arr = ( -- remove objects from list
local currSel = lst.selection
for i = lst.items.count to 1 by -1 where currSel[i] do (deleteItem arr i)
lst.items = for i in arr collect i.name -- update list with array
lst.selection = #{}
)
fn fnClearLst lst arr = ( -- clears list
for i = lst.items.count to 1 by -1 do (deleteItem arr i)
lst.items = for i in arr collect i.name -- update list with array
lst.selection = #{}
)
-----------------------DOT NET CONTROLS--------------------------------
fn fnListviewFactory lv = (
lv.view = lv.view.details
lv.FullRowSelect = lv.GridLines = lv.MultiSelect = on
lv.HideSelection = off
lv.HeaderStyle=lv.HeaderStyle.Nonclickable
lv.HeaderStyle.Nonclickable
lv.Columns.add "Name" 130
)
fn fnAddListItems lv arr = ( -- add Objects to list
curSel = getCurrentSelection()
if curSel.count >= 1 do
(
for o in curSel do (appendIfUnique arr o)
rows=#()
for i = 1 to arr.count do (
li = dotNetObject "System.Windows.Forms.ListViewItem" arr[i].name
li.Font = activeFont
append rows li --Added the listViewItem to the rows array
)
--clear listview before re-populating
if lv.items.count > 0 then lv.EnsureVisible 0
for idx = lv.items.count-1 to 0 by -1 do lv.items.removeat(idx)
lv.items.addRange rows
)
)
fn fnRemoveItems lv arr = (
)
fn fnClearList lv arr = (
if lv.items.count > 0 then lv.EnsureVisible 0
for idx = lv.items.count-1 to 0 by -1 do lv.items.removeat(idx)
)
multiListBox lbxAnimatedObjects "Animated Objects" pos:[10,7] width:120 height:12
dotNetControl lvObjectList "Listview" pos:[140, 10] width:150 height:175
button btnAddAnimObj "+" pos:[60,200] width:30 height:30
button btnRemoveAnimObjs "-" pos:[90,200] width:30 height:30
button btnClearAnimObjs "X" pos:[120,200] width:30 height:30
on lvObjectList mouseDown s a do mouseIsDown = on
on lvObjectList mouseUp s a do mouseIsDown = off
on lvObjectList mouseMove s a do if mouseIsDown and (local item = s.GetItemAt a.x a.y) != undefined do item.selected = on
on lvObjectList MouseDoubleClick s a do
(
itm = s.GetItemAt a.x a.y
if itm != undefined do
(
print itm.text
)
)
on lbxAnimatedObjects rightclick do lbxAnimatedObjects.selection = #{}
on btnAddAnimObj pressed do (
fnAddItmsLst lbxAnimatedObjects AnimObjs
fnAddListItems lvObjectList AnimObjs
)
on btnRemoveAnimObjs pressed do (
fnRemoveItmsLst lbxAnimatedObjects AnimObjs
fnRemoveItems lvObjectList AnimObjs
)
on btnClearAnimObjs pressed do (
fnClearLst lbxAnimatedObjects AnimObjs
fnClearList lvObjectList AnimObjs
)
on rlD open do (fnListviewFactory lvObjectList)
)
createDialog rlD 300 250 style:#(#style_SysMenu, #style_ToolWindow)
Looks like I missed a line in my original post (its the last line in the drawitem func) to help you with #2: Also I don’t know how to over-ride the header so I commented it out for now.
Changes in yellow below:
Have you seen this thread? It may help you.
http://forums.cgsociety.org/showthread.php?f=98&t=689249&page=1&pp=15
Particularly one of the last posts:
http://forums.cgsociety.org/showpost.php?p=5482749&postcount=23
lv.HideSelection = off
lv.BackColor = (dotnetclass "System.Drawing.SystemColors").Menu
This should work, It came from Denis!
http://forums.cgsociety.org/showpost.php?p=7403941&postcount=161