Sunday, February 8, 2009

Visual Inheritance of Statusbars and Toolstrips

I wanted to create a base form that contained a default menu and a default status bar. When I inherited from this form, I wanted to be able to customize the menu and the status bar. After many attempts to get this to work, I realized that it cannot be done in the designer.

I watched an interesting video on Visual Inheritance that confirmed that I was doing things correctly. After I implemented the tutorial for an inherited button, I realized that there was something wrong with menus and status bars.

After searching google for a while, I stumbled on a discussion on the topic. The reference from there was the goldmine: it can't be done!

Back to the drawing board. I will look into adding a second menu to the child form and then adding the menu items to the main form in the base class. The child can still access the menu, it just can't access it at design time in the designer. Sigh.

I have devised a workable solution for the menu strip.
  1. Create a context menu in the child class in the designer; this will support visual editing.
  2. Create a menu item at run time in the child for a new top level menu item.
  3. Set the DropDown event as the context menu.
  4. Insert the top level menu item into the main menu.
//Place in constructor or load event handler
ToolStripMenuItem menuItem = new ToolStripMenuItem("Tools");
menuItem.DropDown = contextMenuStripTools;
this.menuStripBase.Items.Insert(0, menuItem);
Here is another idea:
  1. Add a menu strip to the child. Add all the menu items to it.
  2. Add all the items from the main menu to the base menu.
  3. Access the items in the main menu in reverse order, since each item is moved to the base menu when it is inserted. A foreach cannot be used, since the item collection changes. AddRange won't work for the same reason.
 int count = 0;

 //Use this for loop, or a foreach, to see it crash
 //for (count = 0; count < max; count++)
 //A reverse pass through the items will do the trick
 for (count = menuStripMain.Items.Count - 1; count > -1; count--)
 {
   this.menuStripBase.Items.Insert(0, menuStripMain.Items[count]);
 }

Update: 

The ToolStripManager class has a method that does menu merging like MDI applications.

public static bool Merge(
    ToolStrip sourceToolStrip,
    ToolStrip targetToolStrip
)


ToolStripManager.Merge documentation. Notice that it is a static method.

1 comment:

  1. A simple workaround (which achieves the same effect) is to drop an invisible toolstrip on the sub-form and merge it with the base-forms toolstrip at load time.

    I've developed MergableToolStrip controls you can use free of charge here - http://www.sphere10.com/articles/1/Visual-Inheritance-For-ToolStrip-Controls

    ReplyDelete

Followers