另一个工具箱控件






4.79/5 (52投票s)
2004 年 10 月 26 日
6分钟阅读

332100

8520
另一个类似 Visual Studio 的 ToolBox 控件。
引言
本文介绍了一个 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 对
PaintItems
、DrawPartialItem
控件逻辑进行了小改动。
- Neal Stublen 提供的工具箱项目的
- 11/07/2004
- 带有重命名文本框处理程序的上下文菜单。
- 文本框的位置和字体。
- 鼠标按下时 M 按钮(左右键)的项目状态更改。
- 计时器/滚动延迟获取/设置方法。
- 11/08/2004
- NashControl 指出的一个 bug 和一个小问题已得到修复。
- 更新了演示应用程序。
- 10/10/2005
- 将代码拆分到不同的文件中。
- 项目设置(DLL)的更改。
- 添加了 XML 序列化方法。
- 添加了选项卡和项目的专用集合。
- 添加了更多事件(请参阅 Delegates.cs)。
- 为工具箱项目添加了另外两种视图模式(大图标、小图标视图)。
- 支持大、小图像列表。
- 用于配置选项卡/项目外观的属性。
- 添加了将控件关联到选项卡的支持。
- 在绘图方面进行了更多更改。
- 改进了选项卡和项目的重命名功能。
- 通过拖放交换选项卡、项目。
- 各种其他 bug 修复。
- 更新了演示应用程序。
注释
- 当 XML 序列化工具箱时,您可以使用
OnSerializeObject
和OnDeSerializeObject
事件来处理与工具箱项目关联对象的保存/加载。您也可以在这些事件中保存/加载选项卡的控件信息。 - 通过
SelectAllTextWhileRenaming
和UseItemColorInRename
属性可以配置选项卡/项目的重命名。 - 可以通过
AllowSwappingByDragDrop
属性启用/禁用选项卡/选项卡项目的拖放交换。 - 可以使用
LargeItemSize
、SmallItemSize
属性指定大/小图标视图中选项卡项目的自定义大小。 - 可以通过选项卡的
Control
属性将窗口控件关联到选项卡控件。如果像这样指定了一个控件,该选项卡的工具箱项目将被销毁。 ToolBoxTabs
可以配置为具有不同的外观。请参阅 ToolBoxTab.cs 查看新属性列表。- 如果您在工具箱或工具箱选项卡中指定了
ItemBorderColor
,当鼠标悬停在项目上时,项目将不会以 3D 凸起样式绘制。可以使用ToolBoxTab
或ToolBox
的ItemBackgroundColor
为特定选项卡或所有选项卡提供自定义背景颜色。ItemHoverTextColor
和TabHoverTextColor
可用于在鼠标悬停在上面时提供自定义文本颜色。 - 可以通过按 Ctrl+Tab 或 Ctrl+Shift+Tab 来切换工具箱选项卡。可以使用箭头键和 Tab 键来遍历选项卡项目。
- 您可以通过映射
ToolBox
中的OnBeginDragDrop
事件,将自定义数据格式添加到拖放数据对象中。 ToolBox
、ToolBoxTab
的ShowOnlyOneItemPerRow
属性使在大图标和小图标视图模式下每行只列出一个ToolBoxItem
。