带进度条控件的自定义DataGrid






4.65/5 (25投票s)
2002 年 4 月 26 日
5分钟阅读

260964

10517
展示了如何创建基于DataGrid控件并带有进度列的自定义控件。
引言
当我看到微软的一个演示 SQLXML 用法,关于一个小型项目管理应用的示例时,我对自己说,“如果在数据集中直接拥有类似进度控件的功能那就太酷了”。我经常处理数据,有时数据项是百分比类型,代表某种进度#。用图形化的方式显示这些数据非常有效。
概述
这里我们展示了一个如何实现此功能的小示例。这是一个如何创建派生自 System.Windows.Forms.DataGrid
对象的自定义控件,以及如何编写自定义属性修改对话框的示例。该组件允许使用者指定网格中哪些列是进度类型,然后网格根据指定给网格对象的属性(如进度控件的颜色或样式)进行渲染。
自定义控件
自定义控件项目本身是一个标准的 C# 自定义控件项目。创建时,我只是从自定义项目模板设置了一个新项目。
整个组件实现都放在一个文件中 - CProgressDataGrid.cs
,位于 CProgressControls
命名空间下(我设想也许可以创建更多类似的控件并将它们放在同一个命名空间下)。
正如你从源代码中看到的,类被分成几个区域:访问属性的组件功能 API(通过函数或属性),- 区域命名为 'accessor functions',以及主要部分,实现在名为 'painting functions' 的区域。该区域包含主要的 OnPaint
处理程序。逻辑非常直接:获取标记为进度列类型的列列表,然后对于该列中的每个单元格,获取其值并在那里绘制框。就是这么简单。
属性
你可以通过 Visual Studio 的设计器或组件的 API 来设置控件的一些属性:
- 进度条颜色
- 进度条百分比文本颜色
- 是否显示百分比文本的标志
- 进度样式(可以是 3D、扁平、凹陷或带实线边框)
- 用于填充数据的数据集中的表名
- 列列表
这是用于选择进度控件列的自定义对话框。
要实现自己的属性对话框,你需要执行几个步骤。首先,你需要创建自己的值编辑器类。在本例中,它是 CProgressDataGridColumnsValueEditor
,正如你所见,它派生自 UITypeEditor
类。基本上,你需要重写两个函数 - GetEditStyle
和 EditValue
。GetEditStyle
函数由 VS.NET 框架调用,以检索有关属性使用的编辑器类型的信息,定义了 3 种类型 - Modal
、DropDown
和 None
,有关确切描述,请参阅 UITypeEditorEditStyle
类的文档。
在我们的例子中,我们使用 UITypeEditorEditStyle.Modal
类型。如果你查看 EditValue
函数,你会发现它也非常简单。如果你愿意,可以获取容器的实例,只需将 context.Instance
转换为你的控件类型即可。这里我们有一个类似这样的函数调用:
CProgressDataGrid oGrid = (CProgressDataGrid)context.Instance;
在接下来的几行中,我们创建了用于填充列列表的对话框实例。我不会详细描述用于此目的的窗体(称为 CProgressDataGridColumnsValueEditorForm
),它对这个示例并不重要,但源代码已包含,因此你也可以查看代码的那部分。
一旦属性对话框结束,它将控制权返回给 EditValue
函数,建议在此存储对话框中是否更改了数据的信息并在此处进行检查,如果数据已更改,则只需将数据复制到 value
变量并返回它,以便该值将被存储在属性中。
我有一个 ArrayList
类型的集合,其中保存了被选为进度条列的列,但每当从资源文件中加载持久化数据时,反序列化过程就会出错。我试图找到一个解决方案,但最终放弃了,等我有更多时间时,我会再次深入研究,当然,如果你有任何关于如何让集合作为属性持久化并通过 VS.NET 设计器进行更新的想法,请给我发消息。总之,最后我决定用一个小技巧来处理。该列表存储在字符串属性中,其中列索引由逗号 (,) 分隔符分隔,有一个小的辅助函数可以将字符串转换为 ArrayList
对象。
使用控件
那么,“我该如何使用它?”你可能会问。首先将构建的程序集或源代码放到你的机器上并进行构建(如果是源代码)。完成此操作后,转到工具箱窗口,并在选择某个窗体时右键单击,选择“自定义工具箱”菜单项,然后添加对此程序集的引用。在组件列表的末尾,你会看到 CProgressDataGrid
,将其放置在你的窗体上。
然后你需要指定一个表样式,并根据你的底层数据集添加一些列到样式中。然后你可以向下滚动并找到“进度控件”属性组,指定所需的颜色和类型,是否要显示文本,以及数据集中的表名。完成此操作后,单击 ProgressColumns 属性中的“...”并使用对话框选择你的“进度”列。保存项目并进行构建。
就是这样,如果你有正确的数据集绑定到数据网格,并且在你选择的进度列中有一些数字数据,那么你应该会看到该列中的进度条。
结论
优点
- 简单
- 易于使用
- 多种样式可供选择
- 精简代码
限制
- 无排序支持
- 无列重排支持
- 选定列属性未实现为集合
- 仅支持数据集中的一个表
未来可能的扩展,想法
- 排序支持
- 更多样式
- 就地图形编辑器(类似于 MS Project 中的进度拖动控件)
- 基于单元格(列)的样式,而非仅基于网格(每个单元格都可以有不同的进度)
- 将其变成新的网格单元格对象?(例如
DataGridBoolColumn
)