Windows 的 GraphSheet 控件






3.97/5 (20投票s)
2003年12月3日
4分钟阅读

184833

1385
使用 GDI+ 和 System.Drawing 命名空间在 .NET 中创建的 GraphSheet 控件
引言
在本文中,我打算使用 GDI+ 在 .NET 中创建一个 `GraphSheet` 控件。它是一个简单的控件,使用了 `Graphics` 对象的所有可用功能。我们创建一个“Windows 用户控件”项目的 `GraphSheet` 控件。更多关于该控件及其用法的信息将在下面的“为什么?何时?如何?”中介绍……
代码
代码是自解释的。在这个 `GraphSheet` 控件中,我创建了一个带有网格线的图形工作表位图。我还创建了 `public` 方法,以便更容易地绘制点,并将一组点添加到数组中,然后可以使用该数组绘制线或曲线。还有 `public` 变量可以在图形中引入 X 轴或 Y 轴或两个轴的偏移量。我们还创建了 Boolean
标志来启用或禁用网格线、将刻度单位显示为文本等。
使用控件
将该控件添加到任何 Windows 项目中……然后像使用其他控件一样调用其方法和属性。
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
gs.Xscale_Max = 10
gs.Yscale_Max = 10
gs.Xscale_units = 1
gs.Yscale_units = 1
gs.showBorder = True
gs.displayUnits = True
gs.fontSize = 6
'gs.MarginX = 10
'gs.MarginY = 40
gs.initializeGraphSheet()
gs.AddPoint(1, 1)
gs.AddPoint(2, 5)
gs.AddPoint(3, 3)
gs.AddPoint(5, 5)
gs.AddPoint(7, 5)
gs.AddPoint(9, 9)
gs.AddPoint(7, 9)
gs.AddPoint(4, 6)
gs.DrawGraph(GraphSheetControl.GraphSheet.PlotType.Curve, _
Color.Blue, False)
'gs.DrawPoint(2, 5, Color.SaddleBrown)
End Sub
.NET 和图形
.NET 绝对简化了图形的生成,特别是对于 VB 程序员。如果我们必须在 Visual Basic 6.0 中编写出像这样的优化且灵活的代码,我们必须非常擅长数学。一个很好的例子是 `Graphics` 对象的 `DrawCurve` 方法,它会绘制一条通过传递给它的数组中的点的曲线。如果是在 Visual Basic 6.0 中,就不会这么简单了。
oG.DrawCurve(New Pen(color.red), PointsArray)
不过,.NET 并没有让图形部分的一切都变得容易,至少对于 VB 程序员来说是这样。创建可以完全自行绘制的 Windows 控件并不容易,即使做到了,在生产环境中也不可行。
- 每次控件的 `Paint` 事件触发时,它都必须自行绘制。实现这一点会导致闪烁,事件会不断触发,甚至 MSDN 也建议不要为这类控件在 `paint` 事件中编写代码。
- 对于一个可以自行绘制的控件,我找不到任何简单的机制来将绘图保存为图形对象,以便在重绘期间恢复。我只能找到保存和恢复 `Graphics` 对象状态的方法。看起来绘图只能存储为 `Image`,并且必须从 `Image` 中恢复。在这篇文章的代码中,我更喜欢使用一个简单的机制,即创建一个 `Image` 对象并将其显示在 `PictureBox` 中。
- 图形对象不会自行重绘/刷新,也不会记住它们上次绘制的状态。你必须调用 `Invalidate` 方法来确保你的对象在每次有更改时都更新。
- 你可以在各种表面上绘制,例如 `Form`、`Panel` 等。但如果你使用 `Image` 对象以外的任何东西,你必须在每次绘制时重新绘制。
为什么?何时?以及如何?
嗯,Chris Maunder 对这篇文章发表了评论。天哪,我这是怎么了……这是我看到评论时的第一个想法。:)
GraphSheet 控件是为了让我在一个小型项目中使我的代码更愉快,在那里我需要根据信息动态地绘制图形。添加到本文的图片显示了该项目输出(图片右侧)的一个小片段。
该控件确实使最终代码易于维护。我只需要修改控件中的代码来实现偏移、错误处理等,更改就会影响之后绘制的所有图形。
将与 `Drawing` 和 `Graphics` 命名空间相关的代码隔离后,项目的代码明显得到了极大的缓解。我需要创建任意数量的 `GraphSheet` 控件实例,将数据点添加到控件中(在这里,我们也可以修改控件以支持数据绑定),然后绘制图形。更重要的是,我在控件中创建了逻辑来根据控件的大小调整图形,并在必要时允许偏移。
最重要的是,由于它是一个控件,我可以动态地创建一个实例并将其定位在我的项目中。
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。