65.9K
CodeProject 正在变化。 阅读更多。
Home

另一个工具箱控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.79/5 (52投票s)

2004 年 10 月 26 日

6分钟阅读

viewsIcon

332100

downloadIcon

8520

另一个类似 Visual Studio 的 ToolBox 控件。

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

引言

本文介绍了一个 ToolBox 控件,它具有 VS.NET IDE 工具箱的外观和感觉。大约两周前,我为一个 UI 设计应用程序寻找一个类似工具箱的控件。我偶然发现了 Iulian Serban 的 VS.NET 风格的工具箱及其 Giorgio Santini 的升级版。我最初使用的是那个控件,但后来出现了问题,因为它缺少重命名项目的(我们项目中的一个要求)功能,并且当选项卡过多而项目区域很小时,绘制项目时也存在一些小问题。它的设计相当不错,只是它使用了按钮控件和面板来绘制选项卡和选项卡项目。出于这些原因,我想自己编写一个工具箱控件。

这个 ToolBox 控件是一个完全由所有者绘制的控件,包括动画选项卡移动、交换/重命名选项卡/选项卡项目,当然还有拖放支持 ;)。

关于 ToolBox 控件

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

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

ToolBox 对象维护一个 ToolBoxTab 的数组。当一个 ToolBoxTab 被添加到 ToolBox 时,它会向父控件(ToolBox)注册五个事件。它们是:

  • MouseDown
  • MouseUp
  • MouseMove
  • MouseLeave
  • Paint

当选项卡被移除时,这些事件会被取消注册。当选项卡被禁用时,除了 Paint 事件外,其他事件都会被取消注册;当它被启用时,除了 Paint 事件外,其他事件都会重新注册。

ToolBox 维护两个 ToolScrollButton 对象,分别用于渲染向上和向下的滚动按钮。它还初始化一个隐藏的编辑控件,并将其添加到其控件集合中(这是唯一一个子控件)。

每个 ToolBoxTab 对象维护一个 ToolBoxItem 的数组,可以通过成员方法添加/删除。ToolBoxTab 维护一个名为 itemArea 的矩形,工具箱项目将在此区域内渲染。当选项卡变为未选中状态时,该区域会缩小为一个空的 rect;然后准备并渲染新选中选项卡的 itemRect

当点击滚动按钮或发生鼠标滚轮事件时,项目将被滚动。

如果您想从位图条(就像 MFC CToolBar 一样)设置 ImageList,请使用 ToolBox 的方法 SetImageList(Image image, Size size, Color transparentColor),该方法将按指定大小分割图像,并使用给定的透明颜色创建 ImageList

关注的属性。

  • BackColor:控件的背景颜色。
  • TabHeight:每个选项卡的高度。
  • ItemHeight:每个选项卡项目的高度。
  • TabSpacing:选项卡之间的间距。
  • ItemSpacing:项目之间的间距。
  • ItemHoverColor:鼠标悬停在项目上时的颜色。
  • ItemNormalColor:项目的正常颜色。
  • ItemSelectedColor:选中项目时的颜色。
  • SmallImageList:用于在列表视图和小图标视图中渲染图像的图像列表,其图像索引将被使用。
  • LargeImageList:用于在大图标视图中渲染图像的图像列表,其图像索引将被使用。
  • SmallItemSize:小图标视图中工具箱项目的大小。
  • LargeItemSize:大图标视图中工具箱项目的大小。

使用代码

创建 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);

添加选项卡

// 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);

添加选项卡项目

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);

访问选项卡

ToolBoxTab tab;

//Selected Tab
tab = _toolBox.SelectedTab;

//Any tab
tab = _toolBox[tabIndex];

访问选项卡项目

TooBoxItem item;

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

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

事件

//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);

注意ToolBox 中的某些事件不遵循 .NET 事件处理系统。例如:参见 RenameFinished 事件处理程序的参数。我认为没有必要编写一个 RenameFinishedEventArgs 类 =)。

更新:2005/10/10 - 添加了 RenameFinishedEventArgs

关注点

  • 滚动项目

    起初,项目滚动是通过重新定位选项卡的 itemArea 来实现的。但我不得不放弃,因为我无法正确设置 Graphics 对象的剪裁区域。现在,滚动是通过设置项目的 Y 坐标来实现的,如果其 Y 坐标不完全位于 itemArea 内,则不绘制它。

  • 禁用图像

    在编写此控件时,我一直在研究如何绘制 VS IDE 工具栏中可见的禁用图像。那些图像不是使用 DrawState API 绘制的,这一点很明显。经过一番搜索,我找到了 这个网站,其中作者提到了一个灰度颜色矩阵。它完成了单色转换,但我需要更多的灰色效果。所以,这是我的灰度颜色矩阵:;)

    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);

另一个非常有趣的事情是,我并没有仔细测试这个控件。可能存在 bug 和小问题。(嘘!最好将工具箱包装在一个容器中,例如 Panel,而不是单独放置它。)

为什么是 Silver.UI 命名空间?

我叫 Aju.George。所以是 AG 或 Ag,化学上 Ag 代表银。;)所以是 Me.UI :P

变更

  • 11/06/2004
    • Neal Stublen 提供的工具箱项目的 DragDelay
    • Neal Stublen 对 PaintItemsDrawPartialItem 控件逻辑进行了小改动。
  • 11/07/2004
    • 带有重命名文本框处理程序的上下文菜单。
    • 文本框的位置和字体。
    • 鼠标按下时 M 按钮(左右键)的项目状态更改。
    • 计时器/滚动延迟获取/设置方法。
  • 11/08/2004
    • NashControl 指出的一个 bug 和一个小问题已得到修复。
    • 更新了演示应用程序。
  • 10/10/2005
    • 将代码拆分到不同的文件中。
    • 项目设置(DLL)的更改。
    • 添加了 XML 序列化方法。
    • 添加了选项卡和项目的专用集合。
    • 添加了更多事件(请参阅 Delegates.cs)。
    • 为工具箱项目添加了另外两种视图模式(大图标、小图标视图)。
    • 支持大、小图像列表。
    • 用于配置选项卡/项目外观的属性。
    • 添加了将控件关联到选项卡的支持。
    • 在绘图方面进行了更多更改。
    • 改进了选项卡和项目的重命名功能。
    • 通过拖放交换选项卡、项目。
    • 各种其他 bug 修复。
    • 更新了演示应用程序。

注释

  • 当 XML 序列化工具箱时,您可以使用 OnSerializeObjectOnDeSerializeObject 事件来处理与工具箱项目关联对象的保存/加载。您也可以在这些事件中保存/加载选项卡的控件信息。
  • 通过 SelectAllTextWhileRenamingUseItemColorInRename 属性可以配置选项卡/项目的重命名。
  • 可以通过 AllowSwappingByDragDrop 属性启用/禁用选项卡/选项卡项目的拖放交换。
  • 可以使用 LargeItemSizeSmallItemSize 属性指定大/小图标视图中选项卡项目的自定义大小。
  • 可以通过选项卡的 Control 属性将窗口控件关联到选项卡控件。如果像这样指定了一个控件,该选项卡的工具箱项目将被销毁。
  • ToolBoxTabs 可以配置为具有不同的外观。请参阅 ToolBoxTab.cs 查看新属性列表。
  • 如果您在工具箱或工具箱选项卡中指定了 ItemBorderColor,当鼠标悬停在项目上时,项目将不会以 3D 凸起样式绘制。可以使用 ToolBoxTabToolBoxItemBackgroundColor 为特定选项卡或所有选项卡提供自定义背景颜色。

    ItemHoverTextColorTabHoverTextColor 可用于在鼠标悬停在上面时提供自定义文本颜色。

  • 可以通过按 Ctrl+Tab 或 Ctrl+Shift+Tab 来切换工具箱选项卡。可以使用箭头键和 Tab 键来遍历选项卡项目。
  • 您可以通过映射 ToolBox 中的 OnBeginDragDrop 事件,将自定义数据格式添加到拖放数据对象中。
  • ToolBoxToolBoxTabShowOnlyOneItemPerRow 属性使在大图标和小图标视图模式下每行只列出一个 ToolBoxItem
© . All rights reserved.