protected override void OnClick(EventArgs e) { MenuWithHandler definition = (Tag as MenuWithHandler); if (definition.Target != null) { definition.Target.OnCommand(definition.ID); } // Sometimes all menu texts are blank. I cannot reproduce it. I guess, it is because the menus are not disposed. I debugged by overriding Dispose of ContextMenuWithHandler // If a menu item is clicked, the menu disappears and can be disposed. This is forced here. But if the menu disappears because of some other reason (ESC, click somewhere else) // Dispose doesn't get called until maybe much later or when the form closes. ContextMenuWithHandler toDispose = null; Menu parent = this.Parent; while (parent != null) { if (parent is ContextMenuWithHandler cmh) { toDispose = cmh; break; } if (parent is MenuItem mi) { parent = mi.Parent; } else { break; } } toDispose?.Dispose(); }
void ICanvas.ShowContextMenu(MenuWithHandler[] contextMenu, System.Drawing.Point viewPosition, Action <int> collapsed) { ContextMenuWithHandler cm = MenuManager.MakeContextMenu(contextMenu); ContextMenu = cm; // need to set this in order to get the Collapse event callbackCollapsed = collapsed; cm.Collapse += Cm_Collapse; cm.UpdateCommand(); cm.Show(this, viewPosition); }
internal void ButtonClicked(object sender, EventArgs e) { if (sender is ToolStripSplitButton) { ToolStripSplitButton btn = sender as ToolStripSplitButton; if (!btn.ButtonPressed || lastSubMenuId == "") { // clicked on the dropdown button, or first time click in the button ContextMenuWithHandler cm = MenuManager.MakeContextMenu(MenuResource.LoadMenuDefinition(menuId, false, this)); Control btnParent = parent.GetCurrentParent(); System.Drawing.Point pnt; if (!btnParent.Visible) { pnt = btnParent.PointToScreen(new System.Drawing.Point(btn.Bounds.Left, btn.Bounds.Bottom)); btnParent = Application.OpenForms[0]; pnt = btnParent.PointToClient(pnt); } else { pnt = new System.Drawing.Point(btn.Bounds.Left, btn.Bounds.Bottom); } cm.Show(btnParent, pnt); // if a menu item will be selected, the tagInfo.lastSubMenuId will be set to the selected menu item // and next time, tagInfo.lastSubMenuId will be executed imediately } else { // tagInfo.lastSubMenuId contains the menu id of the last selected menu item. This will be executed bool ok = commandHandler.OnCommand(lastSubMenuId); // if not ok, the command has not been handled } } else { bool ok = commandHandler.OnCommand(menuId); // if not ok, the command has not been handled } }
static internal ContextMenuWithHandler MakeContextMenu(MenuWithHandler[] definition) { ContextMenuWithHandler cm = new ContextMenuWithHandler(definition); return(cm); }
protected override void OnMouseClick(MouseEventArgs e) { base.OnMouseClick(e); (int index, EMousePos position, Rectangle hitItem) = GetMousePosition(e); if (position == EMousePos.onValue && entries[index].Flags.HasFlag(PropertyEntryType.DropDown)) { position = EMousePos.onDropDownButton; } switch (position) { case EMousePos.onTreeButton: int added = entries[index].OpenOrCloseSubEntries(); if (added != 0) { RefreshEntries(-1, 0); } (this as IPropertyPage).Selected = entries[index]; break; case EMousePos.onCheckbox: entries[index].ButtonClicked(PropertyEntryButton.check); break; case EMousePos.onDropDownButton: { ShowDropDown(index); } break; case EMousePos.onCancelButton: entries[index].ButtonClicked(PropertyEntryButton.cancel); break; case EMousePos.onOkButton: entries[index].ButtonClicked(PropertyEntryButton.ok); break; case EMousePos.onContextMenu: if (entries[index].ContextMenu == null) { throw new NotImplementedException("implement ContextMenu of " + entries[index].GetType().ToString() + ", " + entries[index].ResourceId); } ContextMenuWithHandler cm = MenuManager.MakeContextMenu(entries[index].ContextMenu); cm.UpdateCommand(); // ContextMenu OnPopup is not being called cm.Show(this, e.Location); break; case EMousePos.onLabel: if (selected == index && entries[index].Flags.HasFlag(PropertyEntryType.LabelEditable)) { SelectedIndex = index; if (propertiesExplorer.EntryWithTextBox == entries[index]) { propertiesExplorer.HideTextBox(); // there is a textBox open for the value } ShowTextBox(index, e.Location, false); } else { if (entries[index].Flags.HasFlag(PropertyEntryType.Selectable)) { SelectedIndex = index; } } break; case EMousePos.onValue: if (entries[index].Flags.HasFlag(PropertyEntryType.ValueEditable)) { SelectedIndex = index; // before ShowTextBox, because this calls unselected and thus updates the currently textBox or listBox (if any) ShowTextBox(index, e.Location, true); } else { if (entries[index].Flags.HasFlag(PropertyEntryType.Selectable)) { SelectedIndex = index; } if (entries[index].Flags.HasFlag(PropertyEntryType.ValueAsButton)) { entries[index].ButtonClicked(PropertyEntryButton.value); } } break; case EMousePos.onMiddleLine: Cursor = Cursors.VSplit; break; default: Cursor = Cursors.Arrow; break; } }