Context Menus ... On the Fly..

Its been some time since my last post .. Going into the christmas season slows me down a bit... :)...

Now for some Avalon stuff. There was one scenario involving ContextMenus which was pretty interesting. The scenario involved switching between the default context menus and the custom made ones. So lets look at how we go about it.

To begin with if we do not want any Context menu to appear we just set the ContextMenu property on the control to null

tb.ContextMenu = null; //tb is a TextBox

So if we want to bring up a custom ContextMenu all we do is create our own ContextMenu and set it to the contextMenu property. Simple aint it?

Now how do we get back the default menu. The first thought was to set the property to null. But then this disables the contextmenu itself. So the workaround for this is to Clear the property

textbox.ClearValue(ContextMenuProperty).

Now we can change between the custom and default contextMenus on the fly.

Another  question that comes up often is determining whether the context menu has opened or closed. The confusion arises because we have events: Opened and ContextMenuOpening. There is a subtle difference here - If you need to know whether the ContextMenu has Opened then use the Opened event. The same holds for the Closed event.

The ContextMenuOpening event is used to inform controls up the tree that a ContextMenu needs to be opened. This is usually handled in Controls class and that is the reason why we cannot catch the event.

Lets look at some code to make this clear.

 
tb = new TextBox();tb.ContextMenu = null;panel.Children.Add(tb);panel.ContextMenuOpening += new ContextMenuEventHandler(panel_ContextMenuOpening);
 void panel_ContextMenuOpening(object sender, ContextMenuEventArgs e){      tb.ContextMenu = GetContextMenu();} private ContextMenu GetContextMenu(){   MenuItem m1, m2, m3, m4;   ContextMenu _contextMenu = new ContextMenu();   m1 = new MenuItem();   m1.Header = "File";   m2 = new MenuItem();   m2.Header = "Save";   m3 = new MenuItem();   m3.Header = "SaveAs";   m4 = new MenuItem();   m4.Header = "Recent Files";   _contextMenu.Items.Add(m1);   _contextMenu.Items.Add(m2);   _contextMenu.Items.Add(m3);   _contextMenu.Items.Add(m4);   return _contextMenu;} 

in the above code, when we click on the TextBox the event goes up to the panel which then handles it and sets the context menu on the TextBox. Hence, on right clicking the text box we do see a Context menu. Hope this makes things clear!!