Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Another ToolBox Control

0.00/5 (No votes)
19 Oct 2005 4  
Another Visual Studio like ToolBox control.

Sample Image (List View)Sample Image (Small Icon View)Sample Image (Large Icon View)

Introduction

This article is about a ToolBox control which has the look and feel of VS.NET IDE's toolbox. About two weeks back, I was searching for a toolbox like control for an UI design application. I came across Iulian Serban's VS.NET-like Toolbox and its upgrade by Giorgio Santini. I was using that control initially, but later on, I had problems with it, because it lacked the feature of renaming items (a requirement in our project) and also a little problem with drawing items when there were too many tabs and the item area was small. Its design is pretty good except that it uses button controls and panels to draw tabs and tab items. For these reasons, I thought of writing a toolbox control myself.

This ToolBox control is a completely owner drawn control which includes animated tab movements, swapping/renaming tab/tab items, and of course, drag-drop support ;).

About ToolBox Control

Classes:

    +-------------+
    | ToolObject  |
    +------o------+
           |\________
           |         \
    +------o------+    \
    | ToolBoxItem |      \
    +------o------+        \
           |                 \
           |            +----------------+
    +------o------+     |ToolScrollButton|
    | ToolBoxTab  |     +----------------+
    +-------------+

    +-------------+
    | UserControl | // System.Windows.Forms.UserControl
    +-------------+
           |
           |
    +------o------+
    |   ToolBox   |
    +-------------+

The ToolBox object keeps an array of ToolBoxTabs. When a ToolBoxTab is added to the ToolBox, it registers five events with the parent (ToolBox). They are:

  • MouseDown
  • MouseUp
  • MouseMove
  • MouseLeave
  • Paint

These events are un-registered when the tab is removed. When the tab is disabled, the events except Paint is un-registered; and when it is enabled, events except Paint are registered again.

ToolBox keeps two ToolScrollButton objects to render up and down scroll buttons respectively. It also initializes a hidden edit control and adds it to its control collection (the one and only one child control).

Each ToolBoxTab object keeps an array of ToolBoxItems which can be added/deleted through member methods. A ToolBoxTab keeps a rectangle called itemArea into which the toolbox items are rendered. When the tab becomes unselected, this area reduces to an empty rect; and the newly selected tab's itemRect is prepared and rendered.

Items are scrolled when a click occurs in a scroll button or at a mouse wheel event.

If you want to set the ImageList from a bitmap strip (just like in MFC CToolBar), use the method SetImageList(Image image, Size size, Color transparentColor) of ToolBox which will slice the image by the specified size and make the ImageList using the given transparent color.

Properties of interest.

  • BackColor: The background color of the control.
  • TabHeight: Height of each tab.
  • ItemHeight: Height of each tab item.
  • TabSpacing: Spacing between tabs.
  • ItemSpacing: Spacing between items.
  • ItemHoverColor: Color of item when mouse is over it.
  • ItemNormalColor: Normal color of item.
  • ItemSelectedColor: Selected item color.
  • SmallImageList: The imagelist whose image indices are used to render images in list view and small icon view.
  • LargeImageList: The imagelist whose image indices are used to render images in large icon view.
  • SmallItemSize: Size of the tool box item in small icon view.
  • LargeItemSize: Size of the tool box item in large icon view.

Using the code

Creating the ToolBox:

// In your panel or form, add the following code:


using Silver.UI; // At the top, you know ;)


ToolBox _toolBox     = new ToolBox();

_toolBox.BackColor   = System.Drawing.SystemColors.Control;
_toolBox.Dock        = System.Windows.Forms.DockStyle.Fill;
_toolBox.TabHeight   = 18;
_toolBox.ItemHeight  = 20;
_toolBox.ItemSpacing = 1;

_toolBox.ItemHoverColor    = System.Drawing.Color.BurlyWood;
_toolBox.ItemNormalColor   = System.Drawing.SystemColors.Control;
_toolBox.ItemSelectedColor = System.Drawing.Color.Linen;

_toolBox.Name     = "_toolBox";
_toolBox.Size     = new System.Drawing.Size(208, 405);
_toolBox.Location = new System.Drawing.Point(0, 0);

Controls.Add(_toolBox);

Adding a Tab

// Create the tab. (second parameter is the image index)

ToolBoxTab tab = new ToolBoxTab("Tab Name",1);

// Add the tab

_toolBox.AddTab(tab);

// Or add this way

_toolBox.AddTab("Another Tab ",-1);

Adding a Tab item

int tabIndex = 2;

_toolBox[tabIndex].AddItem("Item Caption", 10,
  true, new Rectangle(10,10,100,100));

//Or this way


ToolBoxItem item = new ToolBoxItem();
item.Caption     = "New Item";
item.Enabled     = true;
item.ImageIndex  = 12;
item.Object      = new Rectangle(10,10,100,100);

_toolBox[tabIndex].AddItem(item);

Accessing Tabs

ToolBoxTab tab;

//Selected Tab

tab = _toolBox.SelectedTab;

//Any tab

tab = _toolBox[tabIndex];

Accessing TabItems

TooBoxItem item;

//Selected item.

item = _toolBox.SelectedTab.SelectedItem;

//Any Item

item = _toolBox[tabIndex][itemIndex];

Events

//Notification when a renaming of a tabitem is finished.

_toolBox.RenameFinished += 
  new RenameFinishedHandler(ToolBox_RenameFinished);

private void ToolBox_RenameFinished(ToolBoxItem sender, 
                             RenameFinishedEventArgs e)
{
    // Set e.Cancel to true if rename was not acceptable.

    e.Cancel = true;
}

// Tab Selection change notification

_toolBox.TabSelectionChanged += new 
         TabSelectionChangedHandler(ToolBox_TabSelectionChanged);

private void ToolBox_TabSelectionChanged(ToolBoxTab sender, EventArgs e)
{
    //Add your code

}

// TabItem Selection change notification

_toolBox.ItemSelectionChanged += new 
         ItemSelectionChangedHandler(ToolBox_ItemSelectionChanged);

private void ToolBox_ItemSelectionChanged(ToolBoxItem sender, 
                                                 EventArgs e)
{
    //Add your code

}

//Mapping other events. (Item/Tab mouseup event can be used 

//to show a context menu at the point of click) 

_toolBox.TabMouseDown  += new TabMouseEventHandler(ToolBox_TabMouseDown);
_toolBox.TabMouseUp    += new TabMouseEventHandler(ToolBox_TabMouseUp);
_toolBox.ItemMouseDown += new ItemMouseEventHandler(ToolBox_ItemMouseDown);
_toolBox.ItemMouseUp   += new ItemMouseEventHandler(ToolBox_ItemMouseUp);

Note: Some of the events in ToolBox don't adhere to the .NET event handling system. E.g.: see RenameFinished event handler's parameters. I thought there isn't a need for writing a RenameFinishedEventArgs class =).

Update: 10/10/2005 - Added RenameFinishedEventArgs.

Points of Interest

  • Scrolling Items:

    At first, the scrolling of items was done by repositioning the itemArea of a tab. But I had to abandon that because I couldn't set the Graphics object's clipping region properly. Now, scrolling is done by setting the Y co-ordinate of an item, and if its Y doesn't lie inside itemArea completely, it is not drawn.

  • Disabled Image:

    While writing this control, I was looking on how to draw a disabled image as seen in the VS IDE toolbar. Those images were not drawn using a DrawState API as it can be clearly seen. A little bit of search led me to this site in which the author specifies about a grayscale color matrix. It does the monochrome conversion, but I needed a some more grey effect in it. So, here is my grayscale color matrix: ;)

    ColorMatrix cmtx = null;
    float[][]   matrix = new float[][]
    {
        new float[] {0.3f ,0.3f ,0.3f ,1, 1},
        new float[] {0.1f ,0.1f ,0.1f ,1, 1},
        new float[] {0.1f ,0.1f ,0.1f ,1, 1},
        new float[] {0.3f ,0.3f ,0.3f ,1, 1},
        new float[] {0.08f,0.08f,0.08f,0, 1},
        new float[] {1    ,1    ,1    ,1, 1},
    };
    cmtx  = new ColorMatrix(matrix);

Another really interesting thing is that I have not tested this control keenly. There might be bugs and bunnies. (Pssst! It is better to wrap the toolbox into a container like a Panel rather than leaving it alone.)

Why the namespace Silver.UI?

My name is Aju.George. So it's AG or Ag, chemically Ag means Silver. ;) So it's Me.UI :P

Changes

  • 11/06/2004
    • DragDelay for toolbox items by Neal Stublen.
    • Minor change in PaintItems, DrawPartialItem control logic by Neal Stublen.
  • 11/07/2004
    • Context menu with handlers for rename textbox.
    • Positioning and font for textbox.
    • Item state change for both M-buttons on mouse down.
    • Timer/Scroll delay get/set methods.
  • 11/08/2004
    • A Bug and a Bunnie pointed out by NashControl got fixed.
    • Updated demo application.
  • 10/10/2005
    • Split code to different files.
    • Changes in project settings (DLL).
    • Added XML serialization methods.
    • Added specialized collections of tabs and items.
    • More events added (see Delegates.cs).
    • Two more view modes added for toolbox items (Large Icon, Small Icon View).
    • Support for large and small image lists.
    • New properties to configure tab/items look 'n' feel.
    • Added support to associate a control for a tab.
    • More changes added in drawing.
    • Improved renaming of tabs and items.
    • Swapping of tabs, items by drag drop.
    • Various other bug fixes.
    • Updated demo application.

Notes

  • When xml serializing the toolbox, you can use OnSerializeObject and OnDeSerializeObject events to handle the saving/loading of the object associated with a tool box item. You can also save/load the control info of a tab in these events.
  • Tab/Item Renaming configurable by SelectAllTextWhileRenaming and UseItemColorInRename properties.
  • Swapping of Tab/TabItem can be turned on/off by AllowSwappingByDragDrop property.
  • Custom sizes of tab items in large/small icon view can be specified using LargeItemSize, SmallItemSize property.
  • A window control can be associated with a tab control using it's Control property. If a control is specified like this, the tool box items for that tab will be destroyed.
  • ToolBoxTabs can be configured to have different look 'n' feel. See the ToolBoxTab.cs for a list of new properties.
  • If you specify ItemBorderColor either in toolbox or a toolbox tab, the items will not be drawn with 3D raised style when mouse hovers on it. ItemBackgroundColor of ToolBoxTab or ToolBox can be used to give custom background color for a specific tab or all tabs.

    ItemHoverTextColor and TabHoverTextColor can be used to give custom text color when mouse hovers on it.

  • Toolbox tabs can be switched by pressing Ctrl+Tab or Ctrl+Shift+Tab. Tab items can be iterated by using arrow keys and tab keys.
  • You can add custom data formats to the drag data object by mapping OnBeginDragDrop event in ToolBox.
  • ShowOnlyOneItemPerRow property of ToolBox, ToolBoxTab makes only one ToolBoxItem to be listed per row in Large Icon and Small Icon view mode.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here