ContextMenu problem - MenuItems.Add()

N

Neville Lang

Hi all,

The problem I am having is with a ContextMenu that is called from a
ToolBarButton, set as a PushButton style. The ContextMenu is raised from the
Click event of that button.

For some reason, I found that using the DropDownButton style of a
ToolBarButton would lockup (freeze) some PPCs, like the Toshiba e335 but not
the HP iPAQ 3900 series.

To counter this problem, I decided to use a ToolBarButton with the
PushButton style and link it separately to a Context menu using the Click
event. I can now report that this design now prevents the Toshiba e335 from
freezing, so I have at least fixed that problem. It also continues to work
normally on HP iPAQs.

However, a new problem has emerged. At runtime, I use a method to load a
different set of MenuItems on the ContextMenu depending on some flags. I do
this by using the MenuItem.Clear() method. I now find that while I could do
this with the ToolBarButton set to the DropDownMenu style, I cannot now do
the same thing with a separate ContextMenu triggering it from a Click event
of the ToolBarButton. I get a "System.ArgumentException" error.

It seems Daniel Moth also had a similar problem to this in August 2003.
Katie from Microsoft indicated that it was a bug in CF.

Daniel, did you find a way around this problem of loading different
MenuItems at runtime?

Microsoft, has this problem been fixed yet, maybe with CF v1.0 SP3 beta? It
is still a problem with CF v1.0 SP2.

Does anyone else have a workaround for this known bug?

I suspect this ContextMenu problem might also have something to do with the
freeze on a Toshiba e335 PPC when using the ToolBarButton style set to
DropDownMenu but I cannot be sure.

Regards,
Neville Lang
 
A

Alex Feinman [MVP]

I wonder of you could get aroound it by setting a short (100 msec) one-shot
timer and invoking the menu from the timer event.
Another thing to try is calling Application.DoEvents before doing things
with the menu.
Understand, I'm shooting in the dark here since you haven't provided a code
snippet or a repro project
 
N

Neville Lang

Alex,

To explain, I have MainForm that has a ToolBar added in the designer and the
code snippet below:



private ToolBar toolBar; // from designer

private ToolBarButton toolBarButtonX;
private ContextMenu conMenuX;
private bool condition;
public MenuItem miRep1, miRep2, miRep3, miRep4, miRep5;

public MainForm() // (MainForm Constructor)
{
...
...
InitializeComponent();

// Added these controls outside of designer
this.toolBarButtonX = new ToolBarButton();
this.conMenuX = new ContextMenu();
this.toolBar.Buttons.Add(this.toolBarButtonX);
this.toolBarButtonX.Enabled = true;
this.toolBarButtonX.ImageIndex = 5; // from my code
this.toolBarButtonX.Visible = true;

this.condition = false; // default setting
}

private void InitializeComponent()
{
....
this.miRep1 = new MenuItem();
this.miRep2 = new MenuItem();
this.miRep3 = new MenuItem();
this.miRep4 = new MenuItem();
this.miRep5 = new MenuItem();
....
....

this.miRep1.Enabled = ((bool)(resources.GetObject("miRep1.Enabled")));
this.miRep1.Text = resources.GetString("miRep1.Text");
this.miRep1.Click += new System.EventHandler(this.Rep1_OnClick);

this.miRep2.Enabled = ((bool)(resources.GetObject("miRep2.Enabled")));
this.miRep2.Text = resources.GetString("miRep2.Text");
this.miRep2.Click += new System.EventHandler(this.Rep2_OnClick);

this.miRep3.Enabled = ((bool)(resources.GetObject("miRep3.Enabled")));
this.miRep3.Text = resources.GetString("miRep3.Text");
this.miRep3.Click += new System.EventHandler(this.Rep3_OnClick);

this.miRep4.Enabled = ((bool)(resources.GetObject("miRep4.Enabled")));
this.miRep4.Text = resources.GetString("miRep4.Text");
this.miRep4.Click += new System.EventHandler(this.Rep4_OnClick);

this.miRep5.Enabled = ((bool)(resources.GetObject("miRep5.Enabled")));
this.miRep5.Text = resources.GetString("miRep5.Text");
this.miRep5.Click += new System.EventHandler(this.Rep5_OnClick);

....
....
}

private void toolBar_ButtonClick(object obj, ToolBarButtonClickEventArgs e)
// ToolBar event handler
{
if (e.Button.Equals(this.toolBarButtonX))
{
EventArgs eax = new EventArgs();
ConMenuX_PopUp(this, eax);
}
}

private void ConMenuX_PopUp(object obj, EventArgs ea) // ContexMenu
handler
{
Point pt = new Point(60, 160);
this.conMenuX.Show(this, pt);
}

// This method prepares the ContextMenu to display different reports
depending on a condition
// It is called from another method in the program after the condition is
set
private void PrepRepMenu()
{
this.conMenuX.MenuItems.Clear(); // Kill any current menu
item entries
if (this.condition)
{
this.conMenuX.MenuItems.Add(this.miRep1);
this.conMenuX.MenuItems.Add(this.miRep2); <== Fails here
System.ArgumentException
this.conMenuX.MenuItems.Add(this.miRep4);
this.conMenuX.MenuItems.Add(this.miRep5);
}
else // True if other condition
{
this.conMenuX.MenuItems.Add(this.miRep1);
this.conMenuX.MenuItems.Add(this.miRep2); <== Fails here
System.ArgumentException
this.conMenuX.MenuItems.Add(this.miRep3);
}
}


Apparently, Daniel Moth had a similar problem last year and MS suggested
that these was a bug underthese circumstances.


Regards,
Neville Lang

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
N

Neville Lang

Alex and list,

My earlier post gave the trouble in my main app. I created a test app today
and basically used the code I posted. However, I now find that the test app
ContextMenu works as required but not so in my main app. So, I will need to
look closer at my main app.

Regards,
Neville Lang
 
N

Neville Lang

List,

I have now found why I was getting a System.ArgumentException in my
ContextMenu.

On my previous post, I built a test app and everything worked as reported,
however, my main app did not work correctly and that is where I got the
error message. In checking the differences, I found that for some reason, my
PrepRepMenu() method was being called twice in quick succession. The first
time through, the MenuItems were added correctly to the ContextMenu after
the MenuItems.Clear() was called but on the second call you would get the
error.

Once I removed the cause of the second call to the same method (an error I
made in my code) then the MenuItems were cleared and added correctly at
various other times later in the program when the method was called.

I can only guess that it might have something to do with the GC though I did
not prove it.

This type of error is basically a timing error when you are trying to add
MenuItems to a ContextMenu. Calling the method to add MenuItems in quick
succession will fail but calling the method to add MenuItems after a period
of time has expired will be OK.

This oddity might be one for Microsoft.

Regards,
Neville Lang
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top