Click here to Skip to main content
15,896,154 members
Articles / Programming Languages / C#

IPToolbox: A VS2005-like Toolbox

Rate me:
Please Sign up or sign in to vote.
4.90/5 (50 votes)
25 May 20074 min read 233.3K   7K   162  
A Visual Studio 2005-like ToolBox control which supports almost all features of the original: drag'n'drop, renaming, hiding tabs, items, and disabling items
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace IP.Components
{
    partial class Toolbox
    {
        /// <summary>
        /// Enumerates the default context menu items of the <see cref="Toolbox"/>.
        /// </summary>
        protected enum ContextMenuItems
        {
            /// <summary>
            /// No item.
            /// </summary>
            None = 0,
            /// <summary>
            /// A 'List View' item. Not implemented in default context menus.
            /// </summary>
            ListView,
            /// <summary>
            /// A 'Show All' item.
            /// </summary>
            ShowAll,
            /// <summary>
            /// A 'Choose Items...' item. Not implemented in default context menus.
            /// </summary>
            ChooseItems,
            /// <summary>
            /// A 'Sort alphabetically' menu item.
            /// </summary>
            SortItems,
            /// <summary>
            /// A 'Reset Toolbox' menu item. Not implemented in default context menus.
            /// </summary>
            Reset,
            /// <summary>
            /// An 'Add Tab' menu item.
            /// </summary>
            AddTab,
            /// <summary>
            /// A 'Remove Tab (Item)' menu item.
            /// </summary>
            Remove,
            /// <summary>
            /// A 'Rename Tab (Item)' menu item.
            /// </summary>
            Rename,
            /// <summary>
            /// A 'Move Up' menu item.
            /// </summary>
            MoveUp,
            /// <summary>
            /// A 'Move Down' menu item.
            /// </summary>
            MoveDown,
            /// <summary>
            /// A 'Cut' menu item.
            /// </summary>
            Cut,
            /// <summary>
            /// A 'Copy' menu item.
            /// </summary>
            Copy,
            /// <summary>
            /// A 'Paste' menu item.
            /// </summary>
            Paste
        }

        private static Bitmap _cutImage;
        private static Bitmap _copyImage;
        private static Bitmap _deleteImage;
        private static Bitmap _pasteImage;

        private Bitmap GetMenuImage(string name)
        {
            switch (name)
            {
                case "Cut":
                    if (_cutImage == null)
                    {
                        _cutImage = LoadImage(Properties.Resources.Cut);
                    }
                    return _cutImage;
                case "Copy":
                    if (_copyImage == null)
                    {
                        _copyImage = LoadImage(Properties.Resources.Copy);
                    }
                    return _copyImage;
                case "Delete":
                    if (_deleteImage == null)
                    {
                        _deleteImage = LoadImage(Properties.Resources.Delete);
                    }
                    return _deleteImage;
                case "Paste":
                    if (_pasteImage == null)
                    {
                        _pasteImage = LoadImage(Properties.Resources.Paste);
                    }
                    return _pasteImage;
            }
            return null;
        }

        private static Bitmap LoadImage(Bitmap original)
        {
            Bitmap bitmap = null;
            try
            {
                bitmap = new Bitmap(original);
                bitmap.MakeTransparent(bitmap.GetPixel(0, 0));
            }
            catch (System.IO.FileNotFoundException) { }
            catch (ArgumentNullException) { }
            return bitmap;
        }

        #region Item Menu
        /// <summary>
        /// Creates a default <see cref="ContextMenuStrip">menu</see> to display on <see cref="Item">items</see>.
        /// </summary>
        /// <returns>A formed item <see cref="ContextMenuStrip">context menu</see>.</returns>
        protected virtual ContextMenuStrip CreateItemMenu()
        {
            ContextMenuStrip strip = new ContextMenuStrip();
            strip.Opening += new System.ComponentModel.CancelEventHandler(OnItemMenuOpening);

            ToolStripMenuItem item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuCut);
            item.Image = GetMenuImage("Cut");
            item.Click += new EventHandler(OnMenuItemCutItem);
            item.Tag = ContextMenuItems.Cut;
            strip.Items.Add(item);

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuCopy);
            item.Image = GetMenuImage("Copy");
            item.Click += new EventHandler(OnMenuItemCopyItem);
            item.Tag = ContextMenuItems.Copy;
            strip.Items.Add(item);

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuPaste);
            item.Image = GetMenuImage("Paste");
            item.Click += new EventHandler(OnMenuItemPasteItem);
            item.Tag = ContextMenuItems.Paste;
            strip.Items.Add(item);

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuDelete);
            item.Image = GetMenuImage("Delete");
            item.Click += new EventHandler(OnMenuItemDeleteItem);
            item.Tag = ContextMenuItems.Remove;
            strip.Items.Add(item);

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuRenameItem);
            item.Click += new EventHandler(OnMenuItemRenameItem);
            item.Tag = ContextMenuItems.Rename;
            strip.Items.Add(item);

            strip.Items.Add(new ToolStripSeparator());

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuShowAll);
            item.Click += new EventHandler(OnMenuItemShowAll);
            item.Tag = ContextMenuItems.ShowAll;
            strip.Items.Add(item);

            strip.Items.Add(new ToolStripSeparator());

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuSortAlphabetically);
            item.Click += new EventHandler(OnMenuItemSortAlphabetically);
            item.Tag = ContextMenuItems.SortItems;
            strip.Items.Add(item);

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuResetToolbox);
            item.Click += new EventHandler(OnMenuItemResetToolbox);
            item.Tag = ContextMenuItems.Reset;
            strip.Items.Add(item);

            strip.Items.Add(new ToolStripSeparator());

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuAddTab);
            item.Click += new EventHandler(OnMenuItemAddTab);
            item.Tag = ContextMenuItems.AddTab;
            strip.Items.Add(item);

            strip.Items.Add(new ToolStripSeparator());

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuMoveUp);
            item.Click += new EventHandler(OnMenuItemMoveUp);
            item.Tag = ContextMenuItems.MoveUp;
            strip.Items.Add(item);

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuMoveDown);
            item.Click += new EventHandler(OnMenuItemMoveDown);
            item.Tag = ContextMenuItems.MoveDown;
            strip.Items.Add(item);

            return strip;
        }

        void OnItemMenuOpening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Item caller = ItemMenu.Tag as Item;
            foreach (ToolStripItem stripItem in ItemMenu.Items)
            {
                if (stripItem is ToolStripMenuItem && stripItem.Tag != null && stripItem.Tag is ContextMenuItems)
                {
                    ToolStripMenuItem item = (ToolStripMenuItem)stripItem;
                    ContextMenuItems context = (ContextMenuItems)item.Tag;
                    switch (context)
                    {
                        case ContextMenuItems.ListView:
                            break;
                        case ContextMenuItems.ShowAll:
                            item.Checked = ShowAll;
                            break;
                        case ContextMenuItems.ChooseItems:
                            break;
                        case ContextMenuItems.SortItems:
                            item.Enabled = (caller.Category != null);
                            break;
                        case ContextMenuItems.Reset:
                            break;
                        case ContextMenuItems.AddTab:
                            break;
                        case ContextMenuItems.Rename:
                            item.Enabled = (caller != null);
                            break;
                        case ContextMenuItems.MoveUp:
                            item.Enabled = (caller != null && !IsPointerItem(caller) && caller.Owner.Items.IndexOf(caller) != 0);
                            break;
                        case ContextMenuItems.MoveDown:
                            item.Enabled = (caller != null && !IsPointerItem(caller) && caller.Owner.Items.IndexOf(caller) != caller.Owner.Items.Count - 1);
                            break;
                        case ContextMenuItems.Cut:
                            item.Enabled = (caller != null && !IsPointerItem(caller));
                            break;
                        case ContextMenuItems.Copy:
                            item.Enabled = (caller != null && !IsPointerItem(caller));
                            break;
                        case ContextMenuItems.Paste:
                            item.Enabled = (caller != null && Clipboard.ContainsData(ClipboardFormat.Item));
                            break;
                        case ContextMenuItems.Remove:
                            item.Enabled = (caller != null && !IsPointerItem(caller));
                            break;
                    }
                }
            }
        }
        #endregion

        #region Category Menu
        /// <summary>
        /// Creates a default <see cref="ContextMenuStrip">menu</see> to display on <see cref="Tab">categories</see>.
        /// </summary>
        /// <returns>A formed tab <see cref="ContextMenuStrip">context menu</see>.</returns>
        protected virtual ContextMenuStrip CreateTabMenu()
        {
            ContextMenuStrip strip = new ContextMenuStrip();
            strip.Opening += new System.ComponentModel.CancelEventHandler(OnTabMenuOpening);

            ToolStripMenuItem item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuShowAll);
            item.Click += new EventHandler(OnMenuItemShowAll);
            item.Tag = ContextMenuItems.ShowAll;
            strip.Items.Add(item);

            strip.Items.Add(new ToolStripSeparator());

            item = new ToolStripMenuItem(Properties.Resources.ToolboxTabPasteItem);
            item.Click += new EventHandler(OnMenuItemPasteItem);
            item.Tag = ContextMenuItems.Paste;
            strip.Items.Add(item);

            strip.Items.Add(new ToolStripSeparator());

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuSortAlphabetically);
            item.Click += new EventHandler(OnMenuItemSortAlphabetically);
            item.Tag = ContextMenuItems.SortItems;
            strip.Items.Add(item);

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuResetToolbox);
            item.Click += new EventHandler(OnMenuItemResetToolbox);
            item.Tag = ContextMenuItems.Reset;
            strip.Items.Add(item);

            strip.Items.Add(new ToolStripSeparator());

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuAddTab);
            item.Click += new EventHandler(OnMenuItemAddTab);
            item.Tag = ContextMenuItems.AddTab;
            strip.Items.Add(item);

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuTabDelete);
            item.Click += new EventHandler(OnMenuItemDeleteTab);
            item.Tag = ContextMenuItems.Remove;
            strip.Items.Add(item);

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuRenameTab);
            item.Click += new EventHandler(OnMenuItemRenameTab);
            item.Tag = ContextMenuItems.Rename;
            strip.Items.Add(item);

            strip.Items.Add(new ToolStripSeparator());

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuMoveUp);
            item.Click += new EventHandler(OnMenuItemMoveUp);
            item.Tag = ContextMenuItems.MoveUp;
            strip.Items.Add(item);

            item = new ToolStripMenuItem(Properties.Resources.ToolboxMenuMoveDown);
            item.Click += new EventHandler(OnMenuItemMoveDown);
            item.Tag = ContextMenuItems.MoveDown;
            strip.Items.Add(item);

            return strip;
        }

        void OnTabMenuOpening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Tab caller = TabMenu.Tag as Tab;
            foreach (ToolStripItem stripItem in TabMenu.Items)
            {
                if (stripItem is ToolStripMenuItem && stripItem.Tag != null && stripItem.Tag is ContextMenuItems)
                {
                    ToolStripMenuItem item = (ToolStripMenuItem)stripItem;
                    ContextMenuItems context = (ContextMenuItems)item.Tag;
                    switch (context)
                    {
                        case ContextMenuItems.ListView:
                            break;
                        case ContextMenuItems.ShowAll:
                            item.Checked = ShowAll;
                            break;
                        case ContextMenuItems.ChooseItems:
                            break;
                        case ContextMenuItems.SortItems:
                            item.Enabled = (caller != null);
                            break;
                        case ContextMenuItems.Reset:
                            break;
                        case ContextMenuItems.AddTab:
                            break;
                        case ContextMenuItems.Remove:
                            item.Enabled = (caller != null && caller.AllowDelete);
                            break;
                        case ContextMenuItems.Rename:
                            item.Enabled = (caller != null);
                            break;
                        case ContextMenuItems.MoveUp:
                            item.Enabled = (caller != null && Categories.IndexOf(caller) != 0);
                            break;
                        case ContextMenuItems.MoveDown:
                            item.Enabled = (caller != null && Categories.IndexOf(caller) != Categories.Count - 1);
                            break;
                        case ContextMenuItems.Paste:
                            item.Enabled = (caller != null && Clipboard.ContainsData(ClipboardFormat.Item));
                            break;
                    }
                }
            }
        }
        #endregion

        #region MenuItem handlers
        void OnMenuItemRenameItem(object sender, EventArgs e)
        {
            Item item = ItemMenu.Tag as Item;
            if (item != null)
                OnRenameItem(item);
        }

        void OnMenuItemDeleteItem(object sender, EventArgs e)
        {
            OnDeleteItem(LastSelectedTool as Item);
        }

        void OnMenuItemPasteItem(object sender, EventArgs e)
        {
            IDataObject dataObject = Clipboard.GetDataObject();
            if (dataObject.GetDataPresent(ClipboardFormat.Item))
            {
                Item item = (Item)dataObject.GetData(ClipboardFormat.Item, true);
                ITab selTab = LastSelectedTool as Tab;
                if (selTab == null && LastSelectedTool is Item)
                    selTab = LastSelectedTool.Owner;
                if (selTab != null)
                    OnPasteItem(item, selTab);
            }
        }

        void OnMenuItemCopyItem(object sender, EventArgs e)
        {
            OnCopyItem(LastSelectedTool as Item);
        }

        void OnMenuItemCutItem(object sender, EventArgs e)
        {
            OnCutItem(LastSelectedTool as Item);
        }

        void OnMenuItemMoveDown(object sender, EventArgs e)
        {
            Tab selTab = LastSelectedTool as Tab;
            if (selTab != null && selTab.Owner != null)
            {
                TabCollection tabCollection = selTab.Owner.Categories;
                int index = tabCollection.IndexOf(selTab);
                if (index < tabCollection.Count - 1)
                {
                    bool allowDelete = selTab.AllowDelete;
                    try
                    {
                        selTab.AllowDelete = true;
                        tabCollection.RemoveAt(index);
                        tabCollection.Insert(index + 1, selTab);
                    }
                    finally
                    {
                        selTab.AllowDelete = allowDelete;
                    }
                }
            }

            Item selItem = LastSelectedTool as Item;
            if (selItem != null && selItem.Owner != null)
            {
                ItemCollection itemCollection = selItem.Owner.Items;
                int index = itemCollection.IndexOf(selItem);
                if (index < itemCollection.Count - 1)
                {
                    itemCollection.RemoveAt(index);
                    itemCollection.Insert(index + 1, selItem);
                }
            }
        }

        void OnMenuItemMoveUp(object sender, EventArgs e)
        {
            Tab selTab = LastSelectedTool as Tab;
            if (selTab != null && selTab.Owner != null)
            {
                TabCollection tabCollection = selTab.Owner.Categories;
                int index = tabCollection.IndexOf(selTab);
                if (index > 0)
                {
                    bool allowDelete = selTab.AllowDelete;
                    try
                    {
                        selTab.AllowDelete = true;
                        tabCollection.RemoveAt(index);
                        tabCollection.Insert(index - 1, selTab);
                    }
                    finally
                    {
                        selTab.AllowDelete = allowDelete;
                    }
                }
            }

            Item selItem = LastSelectedTool as Item;
            if (selItem != null && selItem.Owner != null)
            {
                ItemCollection itemCollection = selItem.Owner.Items;
                int index = itemCollection.IndexOf(selItem);
                if (index > 0)
                {
                    itemCollection.RemoveAt(index);
                    itemCollection.Insert(index - 1, selItem);
                }
            }
        }

        void OnMenuItemRenameTab(object sender, EventArgs e)
        {
            Tab caller = LastSelectedTool as Tab;
            if (caller != null)
                OnRenameTab(caller, caller.Text);
        }

        void OnMenuItemDeleteTab(object sender, EventArgs e)
        {
            Tab selected = LastSelectedTool as Tab;
            if (selected != null && selected.Owner != null && selected.AllowDelete)
                selected.Owner.Categories.Remove(selected);
        }

        void OnMenuItemAddTab(object sender, EventArgs e)
        {
            AddEmptyTab();
        }

        void OnMenuItemResetToolbox(object sender, EventArgs e)
        {
            OnResetToolbox();
        }

        void OnMenuItemSortAlphabetically(object sender, EventArgs e)
        {
            OnSortAlphabetically();
        }

        void OnMenuItemShowAll(object sender, EventArgs e)
        {
            ShowAll = !ShowAll;
        }
        #endregion

        /// <summary>
        /// Creates and adds an empty category tab.
        /// </summary>
        /// <remarks>Invoked by the 'Add Tab' menu item.</remarks>
        protected virtual void AddEmptyTab()
        {
            ITab owner = LastSelectedTool as ITab;
            if (owner == null && LastSelectedTool != null)
                owner = LastSelectedTool.Owner;
            if (owner == null)
                owner = this;
            Tab tab = CreateNewTab(GetUnusedCategoryName(owner));
            tab.Opened = true;
            owner.Categories.Add(tab);
            OnPaint(new PaintEventArgs(CreateGraphics(), ClientRectangle));
            OnRenameTab(tab, string.Empty);
        }

        /// <summary>
        /// Sorts currently selected category tab items in ascending order.
        /// </summary>
        /// <remarks>Invoked by the 'Sort Alphabetically' menu item.</remarks>
        protected virtual void OnSortAlphabetically()
        {
            Tab selected = LastSelectedTool as Tab;
            if (selected == null && LastSelectedTool != null)
                selected = LastSelectedTool.Owner as Tab;
            if (selected != null)
                selected.SortItems(SortOrder.Ascending);
        }

        /// <summary>
        /// Resets the state of the <see cref="Toolbox"/>.
        /// </summary>
        /// <remarks>Invoked by the 'Reset Toolbox' menu item.</remarks>
        protected virtual void OnResetToolbox()
        {
        }

        /// <summary>
        /// Copies to the clipboard and removes an <paramref name="item"/> from the <see cref="Toolbox"/>.
        /// </summary>
        /// <param name="item">An <see cref="Item"/> to cut.</param>
        /// <remarks>Invoked by the 'Cut' menu item.</remarks>
        protected virtual void OnCutItem(Item item)
        {
            OnCopyItem(item);
            OnDeleteItem(item);
        }

        /// <summary>
        /// Copies an <paramref name="item"/> to the clipboard.
        /// </summary>
        /// <param name="item">An <see cref="Item"/> to copy.</param>
        /// <remarks>Invoked by the 'Copy' menu item.</remarks>
        protected virtual void OnCopyItem(Item item)
        {
            if (item == null)
                throw new ArgumentNullException("item");

            IDataObject dataObject = new DataObject(ClipboardFormat.Item, item.Clone());
            Clipboard.SetDataObject(dataObject, false);
        }

        /// <summary>
        /// Removes an <paramref name="item"/> from the <see cref="Toolbox"/>.
        /// </summary>
        /// <param name="item">An <see cref="Item"/> to remove.</param>
        /// <remarks>Invoked by the 'Delete' menu item.</remarks>
        protected virtual void OnDeleteItem(Item item)
        {
            if (item == null)
                throw new ArgumentNullException("item");

            if (item.Owner == null)
                throw new ArgumentException(Properties.Resources.ToolboxDeleteNonTabbedItem, "item");

            item.Owner.Items.Remove(item);
        }

        /// <summary>
        /// Inserts an <paramref name="item"/> to the <paramref name="category"/> tab.
        /// </summary>
        /// <param name="item">An <see cref="Item"/> to paste.</param>
        /// <param name="tab">A <see cref="Tab"/> to add an item.</param>
        /// <remarks>Invoked by the 'Paste' menu item.</remarks>
        protected virtual void OnPasteItem(Item item, ITab tab)
        {
            if (item == null)
                throw new ArgumentNullException("item");
            if (tab == null)
                throw new ArgumentNullException("category");
            if (item.Owner != null)
            {
                if (item.Owner == tab)
                    return;

                item.Owner.Items.Remove(item);
            }
            tab.Items.Add(item);
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

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
I@n
Web Developer
Ukraine Ukraine
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions