[Closed] dotNET ContextMenuStrip Question
Hi,
I’m trying to use a ContextMenuStrip to build a right click menu. The problem I’ve got is although the menu is displayed the events aren’t firing when I select a menu item. Would someone mind taking a look at the example below and telling why it doesn’t work please? I’ve highlighted the fn that creates theContextMenuStrip.
(
clearListener()
try(testUI.testDGV.close()) catch()
for b = 1 to 5 do bx = box()
global testUI
struct testUIStr
(
testDGV,
testTab,
fn rcMenuHandler s e =
(
print "rcMenuHandler called!"
),
fn populateDGV tab =
(
local objs = for i = 1 to 5 collect objects[i]
for o in objs do
(
local row = #(getHandleByAnim o, o.name, o.pos.x, o.pos.y, o.pos.z)
tab.rows.add row
)
),
fn defMaxForm =
(
local mf = dotNetObject "MaxCustomCOntrols.MaxForm"
mf.text = "rcMenu Test"
mf.size = dotnetobject "System.Drawing.Size" 500 500
mf
),
fn cellClick s e =
(
if e.button == e.button.right do
(
local cursor = dotnetclass "System.Windows.Forms.Cursor"
local mPt = cursor.Position
rMenu = ::testUI.cms #("Select Oject", "Something")
rMenu.Show mPt.x (mPt.y+5)
)
),
fn defDGV =
(
local dg = dotNetObject "System.Windows.Forms.DataGridView"
dg.Location = dotNetObject "Drawing.Point" 0 0
dg.RowsDefaultCellStyle.BackColor = (dotNetClass "System.Drawing.Color").fromARGB 60 60 60
dg.Visible = true
dg.AllowUserToAddRows = false
dg.AllowUserToDeleteRows = false
dg.AllowUserToOrderColumns = true
dg.AlternatingRowsDefaultCellStyle.BackColor = (dotNetClass "System.Drawing.Color").fromARGB 30 30 30
dg.MultiSelect = off
dg.Dock = dg.Dock.Fill
dg.AutoSize = on
dg.MaximumSize = dotnetobject "System.Drawing.Size" 1920 600
dg.SelectionMode = dg.SelectionMode.CellSelect
dg.AutoSizeRowsMode = dg.AutoSizeRowsMode.AllCells
dg.RowHeadersWidthSizeMode = dg.RowHeadersWidthSizeMode.EnableResizing
dg.RowHeadersVisible = false
dg
),
fn textColumn cn =
(
local col = dotNetObject "DataGridViewTextBoxColumn"
col.headerText = cn
col.readOnly = false
col.minimumWidth = 175
col.AutoSizeMode = (col.AutoSizeMode).fill
col
),
fn fvColumn cn =
(
local col = dotNetObject "DataGridViewTextBoxColumn"
col.headerText = cn
col.readOnly = false
col.resizable = (dotNetClass "DataGridViewTriState").false
col.width = 60
col.ValueType = single
col.DefaultCellStyle.Alignment = col.DefaultCellStyle.Alignment.MiddleRight
col
),
fn hidColumn cn =
(
local col = dotNetObject "DataGridViewTextBoxColumn"
col.headerText = cn
col.readOnly = true
col.Visible = false
col.resizable = (dotNetClass "DataGridViewTriState").false
col.width = 60
col.ValueType = single
col.DefaultCellStyle.Alignment = col.DefaultCellStyle.Alignment.MiddleRight
col
),
fn addColumns dgv =
(
dgv.columns.add (hidColumn "Handle")
dgv.columns.add (textColumn "Name")
dgv.columns.add (fvColumn "X-Pos")
dgv.columns.add (fvColumn "Y-Pos")
dgv.columns.add (fvColumn "Z-Pos")
),
fn cms itemsArr =
(
local cmsMenu = dotNetObject "System.Windows.Forms.ContextMenuStrip"
for i = 1 to itemsArr.count do
(
cmsMenu.Items.Add(itemsArr[i])
dotnet.addEventHandler cmsMenu.Items.item[i-1] "Click" this.rcMenuHandler
)
cmsMenu
),
fn buildUI =
(
testDGV = defMaxForm()
testTab = defDGV()
addColumns testTab
populateDGV testTab
dotNet.addEventHandler testTab "CellMouseClick" cellClick
testDGV.controls.add testTab
testDGV.showModeless()
),
start = buildUI()
)
::testUI = testUIStr()
)
Thanks.
This is only based on a quick glance but I guess it is because you are not keeping a reference to your menu items, therefore they are going out of scope and getting garbage collected. Either set their lifetime to #dotnet or keep a reference to them in your struct.
Thanks for the replies. I’ve just been trying your suggestions and everything is working as expected now.
I think the main problem was my poor planning. I was trying to define the contextMenuStrip and its events inside a function which was itself being called by a cellClick event.
I’ve also added members to the structure to store the menu and menu items to protect them from garbage collection.