首页 > 编程 > .NET > 正文

从头创建 Visual Basic .NET 控件 (五)

2024-07-10 13:04:02
字体:
来源:转载
供稿:网友
第 4 步:绘制控件的外观
要使控件具有一个可视的外观,我们需要在 paint 事件中放置逻辑。然后,每次控件需要刷新其可视外观时,就会运行该逻辑。

windows 窗体中的 paint 逻辑使用 .net 中 gdi+ 部分中的类。这些类基本上包括了 windows api 图形功能。由于适合 .net,所以比 api 更易于使用。但是,有关它们的工作原理,需要理解以下几点。

在 windows api 中,图形操作需要一个窗口句柄,有时称为 hwnd。在 gdi+ 中,它由 graphics 对象取代,该对象不仅代表了绘图区域,还提供在该区域执行的操作(方法)。

例如,graphics 对象具有以下方法,可用来绘制各种屏幕元素:

drawcurve
drawellipse
drawline
drawpolygon
drawrectangle
drawstring
fillellipse
fillpolygon
这些都是很容易理解的,只是可用方法的示例。一些更复杂的方法还允许旋转对象。我们将使用 drawrectangle 方法绘制边框,使用 fillellipse 方法绘制彩色的圆。

大多数绘图方法都要求使用 pen 或 brush 对象。pen 对象用于绘制直线并确定直线的颜色和粗细。brush 对象用于填充区域、确定填充区域所使用的颜色,以及一些特殊效果(例如,用位图填充区域)。我们将使用特殊的 brush 效果使当前没有亮起的灯的颜色变暗。

下面是处理控件的 paint 事件的代码:

protected overrides sub onpaint(byval pe as _
                        system.windows.forms.painteventargs)
    mybase.onpaint(pe)

    dim grfgraphics as system.drawing.graphics
    grfgraphics = pe.graphics

    ' 首先绘制三个代表灯的圆。
    ' 一个亮起,其余两个熄灭。
    drawlight(trafficlightstatus.statusgreen, grfgraphics)
    drawlight(trafficlightstatus.statusyellow, grfgraphics)
    drawlight(trafficlightstatus.statusred, grfgraphics)

    ' 现在绘制红绿灯周围的轮廓
    ' 用画笔绘制轮廓,将它涂成黑色。
    dim pendrawingpen as new _
        system.drawing.pen(system.drawing.color.black, msngborderwidth)

    ' 在控件上绘制红绿灯的轮廓。
    ' 首先定义要绘制的矩形。
    dim rectborder as system.drawing.rectangle

    rectborder.x = 1
    rectborder.y = 1
    rectborder.height = me.height - 2
    rectborder.width = me.width - 2
    grfgraphics.drawrectangle(pendrawingpen, rectborder)

    ' 释放图形对象
    pendrawingpen.dispose()
    grfgraphics.dispose()

end sub

首先使用基类绘制,它通常使用控件的背景颜色绘制背景。然后,从事件参数中获取控件的 graphics 对象。

接下来,用一个函数画出三个圆。有关该函数的内容稍后介绍。请注意,我们必须向该函数传递一个 graphics 对象的引用,同时还要指示要画的圆(红、黄、绿)。

然后是绘制轮廓的代码。声明一个具有适当位置和大小的矩形,然后传递给 graphics 对象的 drawrectangle 方法。

最后,图形对象激活其 dispose 方法。使用 gdi+ 时,最好在完成图形对象后立即释放它们。这有助于清除操作系统绘图时所用的资源。如果要在 windows® 98 或 windows me 中使用控件,管理图形资源就更加重要,因为这些操作系统处理这种资源的能力较差。

下面是绘制圆的函数:

private sub drawlight(byval lighttodraw as trafficlightstatus, _
                      byval grfgraphics as graphics)

    dim ncirclex as integer
    dim ncircley as integer
    dim ncirclediameter as integer
    dim ncirclecolor as color

    ' 找到所有圆的 x 坐标和直径
    ncirclex = cint(me.size.width * 0.02)
    ncirclediameter = cint(me.size.width * 0.96)
    select case lighttodraw
        case trafficlightstatus.statusred
            if lighttodraw = me.status then
                ncirclecolor = color.orangered
            else
                ncirclecolor = color.maroon
            end if
            ncircley = cint(me.size.height * 0.01)
        case trafficlightstatus.statusyellow
            if lighttodraw = me.status then
                ncirclecolor = color.yellow
            else
                ncirclecolor = color.tan
            end if
            ncircley = cint(me.size.height * 0.34)
        case trafficlightstatus.statusgreen
            if lighttodraw = me.status then
                ncirclecolor = color.limegreen
            else
                ncirclecolor = color.forestgreen
            end if
            ncircley = cint(me.size.height * 0.67)

    end select
    dim bshbrush as system.drawing.brush
    if lighttodraw = me.status then

        bshbrush = new solidbrush(ncirclecolor)
    else
        bshbrush = new solidbrush(color.fromargb(60, ncirclecolor))
    end if

    ' 绘制代表红绿灯的圆
    grfgraphics.fillellipse(bshbrush, ncirclex, ncircley, ncirclediameter, ncirclediameter)

    ' 释放笔刷
    bshbrush.dispose()

end sub

这是整个控件中唯一的一个复杂图形。在 gdi+ 中,在要绘制椭圆的矩形中指定左上角的 x 坐标和 y 坐标,然后指定矩形的高度和宽度即可绘制一个椭圆。我们分别将 x 坐标和 y 坐标称为 ncirclex 和 ncircley。因为我们要绘制一个圆,因此矩形的高度等于宽度,用变量 ncirclediameter 来控制该值。

将 ncirclex 设置为刚好放到控件内(控件的宽度乘以 0.02)。ncircley 取决于要绘制哪个灯,可以设置成靠近控件的顶部(红灯)、大约向下三分之一(黄灯)或大约向下三分之二(绿灯)。直径 ncirclediameter 设置为等于控件宽度的 96%。

要绘制实心椭圆,还需完成一件事,即确定要使用的颜色。颜色取决于正在绘制哪个灯以及正在绘制的灯是否亮起。亮起的灯的颜色要比熄灭的灯的颜色亮。

创建绘图要使用的笔刷时需要使用这些颜色。如果正在绘制的灯是亮起的,即使用该颜色。如果绘制的灯是熄灭的,则要使用不同的方法实例化笔刷。下面是熄灭的灯所使用笔刷的代码行:

bshbrush = new solidbrush(color.fromargb(60, ncirclecolor))

这并不是 .net 中较好的方法名,但 fromargb 方法的作用是创建笔刷,并通过将笔刷与背景颜色相结合来淡化颜色。第一个参数使用的数字介于 0 至 255 之间,数字越小,背景颜色渗透越深。我们使用的值为 60,它将大大降低处于熄灭状态的灯的颜色。您可以尝试对该参数使用不同的值(或将它设置成可设置属性),以获得不同的效果。

最后,graphics 对象的 drawellipse 方法绘制出该圆,函数结束。记住,该函数需要调用三次以绘制三个不同的圆。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表