Click here to Skip to main content
15,880,796 members
Articles / Multimedia / GDI+
Article

Another ToolBox Control

Rate me:
Please Sign up or sign in to vote.
4.79/5 (53 votes)
19 Oct 20056 min read 321.1K   8.5K   193   79
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:

C#
// 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

C#
// 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

C#
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

C#
ToolBoxTab tab;

//Selected Tab
tab = _toolBox.SelectedTab;

//Any tab
tab = _toolBox[tabIndex];

Accessing TabItems

C#
TooBoxItem item;

//Selected item.
item = _toolBox.SelectedTab.SelectedItem;

//Any Item
item = _toolBox[tabIndex][itemIndex];

Events

C#
//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: ;)

    C#
    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


Written By
Web Developer
India India
Yet another programmer =)

Comments and Discussions

 
GeneralSystem.ArgumentOutOfRangeException was caught Pin
Subodh Taneja27-Jan-10 22:32
Subodh Taneja27-Jan-10 22:32 
AnswerRe: System.ArgumentOutOfRangeException was caught [modified] Pin
Subodh Taneja28-Jan-10 23:43
Subodh Taneja28-Jan-10 23:43 
GeneralHello, how to change selected item during runtime? [modified] Pin
rejectkosta21-Jan-10 1:33
rejectkosta21-Jan-10 1:33 
GeneralGreat ToolBox, but there's a bug with the ItemSelectionChanged [modified] Pin
Adagio.8127-Nov-08 22:57
Adagio.8127-Nov-08 22:57 
GeneralVisual studio 2005 version Pin
gdrobinson19-Aug-08 11:28
gdrobinson19-Aug-08 11:28 
GeneralExactly what i need Pin
codeadair28-May-08 20:53
codeadair28-May-08 20:53 
GeneralItems Pin
mikeroku20-Mar-08 13:01
mikeroku20-Mar-08 13:01 
GeneralSome design time enhancements would be nice... Pin
mikeroku19-Mar-08 20:49
mikeroku19-Mar-08 20:49 
QuestionRightToLeft? Pin
m_jahedbozorgan26-Jan-08 21:35
m_jahedbozorgan26-Jan-08 21:35 
Generalgreat control Pin
vmsn11-Dec-07 22:32
vmsn11-Dec-07 22:32 
great control
QuestionCan you give me some instructions? Pin
sherlockhua19-Oct-07 4:24
sherlockhua19-Oct-07 4:24 
GeneralGood Tool Pin
Fernando Hitch9-Oct-07 7:33
Fernando Hitch9-Oct-07 7:33 
QuestionWrong figures after clicking ToolboxItems Pin
J.Thomas20-Jul-07 0:32
J.Thomas20-Jul-07 0:32 
GeneralForm Editor Pin
Daniel Endeg26-Jun-07 5:51
Daniel Endeg26-Jun-07 5:51 
Questionimage can not display Pin
Akrm16-Feb-07 7:45
Akrm16-Feb-07 7:45 
GeneralDragging tab items onto a picture box Pin
Praveen Naregal4-Dec-06 19:40
Praveen Naregal4-Dec-06 19:40 
QuestionGreat tool Pin
Vikas Salvi13-Sep-06 22:54
Vikas Salvi13-Sep-06 22:54 
AnswerRe: Great tool Pin
friendly_coder14-Sep-06 7:15
friendly_coder14-Sep-06 7:15 
Generaljust a little bug Pin
friendly_coder12-Sep-06 2:26
friendly_coder12-Sep-06 2:26 
GeneralRe: just a little bug Pin
VINUM16-Jan-07 7:19
VINUM16-Jan-07 7:19 
GeneralBug in ProcessCmdKey Pin
ladeda22-Aug-06 23:48
ladeda22-Aug-06 23:48 
Generalquestion Pin
muti215-Aug-06 22:27
muti215-Aug-06 22:27 
Generalno change in Selectedtab value. Pin
rottie5-Jul-06 4:32
rottie5-Jul-06 4:32 
AnswerRe: no change in Selectedtab value. Pin
Aju.George6-Jul-06 4:46
Aju.George6-Jul-06 4:46 
Generalscrollbar needed Pin
odelia_jct30-May-06 0:24
odelia_jct30-May-06 0:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.