Reputation: 110
I've added a contextmenustrip programmatically through the extension of panel along with some other stuff, It is being set into the panel's contextmenu through the panel's constructor.
The first time I right click does not work and then it will after the first time always.
I have tried also to put the constructor of the contextmenustrip and the assigning of it to the panel's context menu in other places such as Load and the form's constructor and even in a timer with a flag, All produced the same result..
EDIT:(Some code as requested(as it is and cut to important points))
class FiniteAutomationController : System.Windows.Forms.Panel
{
public FiniteAutomationController()
: base()
{
this.ContextMenuStrip = (cms = new ContextMenuStrip());
}
public ContextMenuStrip cms;
}
EDIT:(Per blaze_125's request, some more code)
//at form designer initializecomponents after Controller(FiniteAutomationController)'s initialization
this.Controller.cms.Opening += new System.ComponentModel.CancelEventHandler(this.cms_Load);
//at form code class
static State contextS = null;
static Action contextA = null;
private void cms_Load(object sender, CancelEventArgs e)
{
Controller.cms.Items.Clear();
if ((contextS = FiniteAutomationData.GetStateFrom(mouseX, mouseY)) != null) // Rclick States
{
Controller.cms.Items.Add("Delete"); Controller.cms.Items[0].Click += new EventHandler(cms_DeleteState);
Controller.cms.Items.Add("Rename"); Controller.cms.Items[1].Click += new EventHandler(cms_RenameState);
Controller.cms.Items.Add((contextS.final ? '\u2714' : ' ') + " Final"); Controller.cms.Items[2].Click += new EventHandler(cms_Final);
Controller.cms.Items.Add((contextS.initial ? '\u2714' : ' ') + " Initial"); Controller.cms.Items[3].Click += new EventHandler(cms_Initial);
Controller.cms.Items.Add("Trap"); Controller.cms.Items[4].Click += new EventHandler(cms_Trap);
if (!contextS.error.Equals(""))
{
Controller.cms.Items.Add("Error: " + contextS.error);
Controller.cms.Items[5].Enabled = false;
}
}
else if((contextA = FiniteAutomationData.GetActionFrom(mouseX,mouseY)) != null) // Rclick Action
{
Controller.cms.Items.Add("Delete"); Controller.cms.Items[0].Click += new EventHandler(cms_DeleteAction);
}
else // Rclick null
{
Controller.cms.Items.Add("Add State"); Controller.cms.Items[0].Click += new EventHandler(cms_AddState);
}
}
Upvotes: 1
Views: 2601
Reputation: 836
Add a MouseClick event to notifyicon. Handle the event as the following:
private void NotifyIconClicked(object sender, MouseEventArgs e)
{
_dashboard.ShowHiddenWindow();
if (e.Button == MouseButtons.Right)
{
MethodInfo ShowContextMenu = typeof(NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.Instance | BindingFlags.NonPublic);
if (ShowContextMenu != null)
{
ShowContextMenu.Invoke(_notifyIcon, null);
}
}
}
I believe the main window has to be made active for this, but I haven't tested this conditional for sure. This is something that i had to implement anyway.
internal static void ShowHiddenWindow(this Window window)
{
try
{
if (!window.IsVisible)
{
window.Show();
}
if (!window.IsFocused)
{
window.Activate();
}
window.WindowState = WindowState.Normal;
}
catch
{
// Avoids "Cannot set visibility while window is closing".
}
}
Upvotes: 0
Reputation: 173
I found (well, with the help of DotPeek) that when using a blank ContextMenuStrip
for a Control
's ContextMenuStrip
property so that you can add the items dynamically the code in System.Windows.Forms
actually sets the Cancel
property of the CancelEventArgs
that are passed to the Opening
handler to true
because the context menu at first is empty and contains no items.
On subsequent calls, even if the first thing you do in the Opening
handler is clear all items, the Cancel
property will be set to false
.
So my fix to make sure the context menu shows up at all times (including the first one) was to always set the CancelEventArgs
' Cancel
property to true
or false
and not (falsely) relying on it to be initialized to false
anyway...
Upvotes: 4
Reputation: 58
For my case, I need to show the context menu by clicking on ToolStripButton. It is not shown for the first click. I managed this problem in this way
void _TsiMenu_Click(object sender, EventArgs e)
{
AdjustableMenu.Show(this, this.PointToClient(Cursor.Position), ToolStripDropDownDirection.Default);
Application.DoEvents();
if (AdjustableMenu.Visible == false)
AdjustableMenu.Show(this, this.PointToClient(Cursor.Position), ToolStripDropDownDirection.Default);
}
Upvotes: 0
Reputation: 110
Throughout the last 3 days I've managed to find a solution which I think is a really bad one, but a solution still..
What I did is used the MouseDown Event of the Controller and using a flag, Showed the context menu on the first time using it's Show(Point) method.
The show method placed the menu a bit off and I settled on "new Point(e.X,e.Y+45)" to place it correctly which still I don't like that I'm doing as it seems really unprofessional..
Thanks anyways I guess..
Upvotes: 0