Wednesday, February 12, 2014

Vertical MenuStrip in C#

As part of a long term project which requires the creation of many custom controls, I recently encountered a hang-up on one in particular: the menu. At a first glance, all there really needs to be done is to override the various paint methods in an extended version of the ToolStripRenderer class and insert my fancy drawing code. However, the real problem came when I needed to render a menu like a ContextMenuStrip only in a window.

With a bit of quick research and perusing through the libraries, I learned of the Layout feature and how Dock still works even in MenuStrips. By setting Dock to Fill and Layout to VerticleStackWithOverflow, I should get the desired result right. Not so! This was still a menu and menu's do not render hot-keys, images, check-states, or ancestry. I didn't know it yet, but three days later (three days of hacking together something clunky by similar) I realized I could mask the under-the-hood functionality with emulation using the very same custom renderer that makes my menus look pretty.

My end result, a windowed context menu:

Solution:
In the method call to 'OnRenderMenuItemBackground,' make an additional call to OnRenderItemText (for the shortcut display string), OnRenderArrow (only if the item has children), and OnRenderItemCheck (only if the item is marked as checked). You will need to give your own rectangles but that's all part of the fun of rendering!


Some may ask: "What use does this have?"
The answer is simple; Based on developer feedback from professional media industries, when one has over a hundred or so menu items to choose from, the user can get lost real quickly. And even if they knew where things are, it still requires a bit of time to navigate the menu hierarchy before finally selecting the very menu item. If you have ever been involved in a large scale project where deadlines need to be met, you will agree that time is precious. Accessing the menu item may take only a second or two in real time, but this all adds up. So a solution like this is more of a necessary optimization: The user selects the key menu that is accessed often and turns it into a painter's pallet. And when they're done, they simply close the window - the menu will still be available where all other menus are located.

No comments:

Post a Comment