[Closed] Eventhandlers in an xtraTreelist
Hello,
I’m working on a script which uses the xtraTreelist. I like this control because it’s pretty easy to create a very comprehensive gui with different types of controls. Although many of the controls work fine, I run into a specific problem with evenhandlers. In the example below there’s a control with a treelist, a few nodes and a button in every node. I want to give a different evenhandler to specific buttons. In this example I’ve given the first button an event and the other buttons a different event. The problem is that these events only work on the first button you click. After that the handlers don’t work.
I’m at a loss how to create these handlers and make them stick. Maybe somebody can help me with this?
global struct_guiForm
try(struct_guiForm.maxForm.close())catch()
struct struct_guiForm
(
maxForm = dotNetObject "MaxCustomControls.MaxForm",
tl = dotnetObject "DevExpress.XtraTreeList.TreeList",
f, --placeholder for eventhandlers
function fn_initForm control =
(
--init the form
control.Size = dotNetObject "System.Drawing.Size" 450 300
control.Text = "Test for evenhandlers in an xtraTreelist - Klaas Nienhuis 2011"
),
function fn_initTl control =
(
--init the treelist
control.Dock = control.Dock.fill
control.ShowButtonMode = control.ShowButtonMode.ShowAlways --
--create the repositoryitem
local repButton = dotNetObject "DevExpress.XtraEditors.Repository.RepositoryItemButtonEdit"
repButton.name = "repButton"
repButton.buttons.item[0].kind = repButton.buttons.item[0].kind.glyph
repButton.buttons.item[0].caption = "Press me!"
--add the editor to the repository
control.RepositoryItems.Add repButton
),
function fn_populate control =
(
--populate the treelist
--create a column
local col=control.columns.add()
col.visible=true
col.caption= "The column"
--create a few treelist nodes
for i = 1 to 10 do control.AppendNode #(("Item" + (i as string))) -1
),
--this event adds the button from the repository to the nodes. I use this event because i can specify the editor
--very precisely to nodes. In this example i just add the same buttonEdit to all nodes.
function event_addEditor control arg = arg.repositoryItem = control.repositoryItems.item["repButton"],
--this event adds a custom eventhandler to the buttonEdit. It should add the event when the node is
--activated. My problem: it only seems to work with the first node. Every following node doesn't get the handler.
function event_shown control arg =
(
case of
(
(control.focusedNode.item[0] == "Item1"): --add a handler to the first item
(
dotNet.addEventHandler control.activeEditor.properties "ButtonClick" (function handlerFunction control arg = print "Item 1 has been pressed")
)
default: --add a different handler to the other items
(
dotNet.addEventHandler control.activeEditor.properties "ButtonClick" (function handlerFunction control arg = print "Any other item has been pressed")
)
)
),
handler = dotNet.addEventHandler tl "CustomNodeCellEdit" (function f control arg = struct_guiForm.event_addEditor control arg),
handler = dotNet.addEventHandler tl "shownEditor" (function f control arg = struct_guiForm.event_shown control arg),
initForm = fn_initForm maxForm,
initTl = fn_initTl tl,
populateTl = fn_populate tl,
assembleForm = maxForm.controls.add tl,
showForm = maxForm.ShowModeless()
)
struct_guiForm = struct_guiForm()
So just to be clear, when pressing any of the buttons something should be printed to the listener. Execute this script, press one button (works fine), press another button (doesn’t work), press the first button again (also doesn’t work).
This might be happening because of Garbage Collection removing the event handlers after the 1st click. I know this was a issue with other UI setups. Not sure though…
yeah, in max 2010 there’s a new method to prevent dotnet eventhandlers from being trashed by max-garbage collection. I’ve tried to implement that, but it didn’t work. Maybe I’ve been doing in wrong though.
Klaas
Hi,
for those who are interested, I’ve solved my problem. When adding the eventhandlers to the buttons the moment the button is created, the handler will be persistent. Here’s the example. There are two different buttons in the repository, both with a different handler. Depending on the name of the treenode, I assign the button to the node.
global struct_guiForm
try(struct_guiForm.maxForm.close())catch()
struct struct_guiForm
(
maxForm = dotNetObject "MaxCustomControls.MaxForm",
tl = dotnetObject "DevExpress.XtraTreeList.TreeList",
f, --placeholder for eventhandlers
function fn_initForm control =
(
--init the form
control.Size = dotNetObject "System.Drawing.Size" 450 300
control.Text = "Test for evenhandlers in an xtraTreelist - Klaas Nienhuis 2011"
),
function fn_initTl control =
(
--init the treelist
control.Dock = control.Dock.fill
control.ShowButtonMode = control.ShowButtonMode.ShowAlways
--create the repositoryitems
--both buttons have different names and different eventhandlers. These will be sticky and won't be garbage-collected.
local repButton = dotNetObject "DevExpress.XtraEditors.Repository.RepositoryItemButtonEdit"
repButton.name = "repButton"
repButton.buttons.item[0].kind = repButton.buttons.item[0].kind.glyph
repButton.buttons.item[0].caption = "Press me!"
dotNet.addEventHandler repButton "ButtonClick" (function handlerFunction control arg = format "Item 1 has been pressed
")
local repButton2 = dotNetObject "DevExpress.XtraEditors.Repository.RepositoryItemButtonEdit"
repButton2.name = "repButton2"
repButton2.buttons.item[0].kind = repButton2.buttons.item[0].kind.glyph
repButton2.buttons.item[0].caption = "Press me too!"
dotNet.addEventHandler repButton2 "ButtonClick" (function handlerFunction control arg = format "Any other item has been pressed, this is %
" control.text)
--add the editor to the repository
control.RepositoryItems.Add repButton
control.RepositoryItems.Add repButton2
),
function fn_populate control =
(
--populate the treelist
--create a column
local col=control.columns.add()
col.visible=true
col.caption= "The column"
--create a few treelist nodes
for i = 1 to 10 do control.AppendNode #(("Item" + (i as string))) -1
),
--this event adds the buttons from the repository to the nodes. depending on the name of the node, one ore the other
--button is added
function event_addEditor control arg =
(
case arg.node.item[0] of --add different buttons to the node, depending on the name of the node
(
"Item1": arg.repositoryItem = control.repositoryItems.item["repButton"]--add a button to the first item
default: arg.repositoryItem = control.repositoryItems.item["repButton2"]--add a different button to the other items
)
),
handler = dotNet.addEventHandler tl "CustomNodeCellEdit" (function f control arg = struct_guiForm.event_addEditor control arg),
initForm = fn_initForm maxForm,
initTl = fn_initTl tl,
populateTl = fn_populate tl,
assembleForm = maxForm.controls.add tl,
showForm = maxForm.ShowModeless()
)
struct_guiForm = struct_guiForm()