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

目标闪烁板 (GDI+ 轻松实现)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.94/5 (15投票s)

2009年9月8日

CPOL

3分钟阅读

viewsIcon

62600

downloadIcon

1502

展示了如何仅使用 GDI+ 轻松创建 WinForms 用户控件。

Frankfurt International Airport Departure Board

引言

本文将向您展示如何使用 System.Drawing 类(也称为 GDI+)创建一个 .NET UserControl,用于显示类似于机场旧的到达/出发板的信息。当每一行发生变化时,该板将通过字母表闪烁以显示新条目。

本文的目的不是为了教你如何成为 GDI+ 专家。它实际上是为了表明 GDI+ 并没有许多人想象的那么难。它的目的是鼓励开发人员在现有控件无法满足需求,或者当您想为您的 Winforms UI 演示添加一些润色时,创建自定义控件。

Using the Code

一旦您将 AirportDepartureBoard 控件添加到您的表单中,您会发现您无法向控件添加或删除行。因此,更改行文本的唯一方法是调用控件的 UpdateRow 方法。最好在初始化表单时将闪烁设置为 Flicker.No。这将避免减慢表单的加载时间。

MyDepartureBoard.UpdateRow(0, “Hello World” Flicker.No);

初始化后,要使闪烁生效,请在更新行的文本时将 Flicker 参数设置为 Flicker.Yes

MyDepartureBoard.UpdateRow(1, “It’s a beautiful day” Flicker.Yes);

下载源代码中的 AirportDepartureBoard 控件是使用 Croll.Windows.Forms.DestinationBoard 控件的一个例子,该控件完成了大部分工作。DestinationBoard 控件具有许多您可以在设计时或运行时设置的属性。这些是 BoardBackColor, BoardRowDividerColorBoardFlickerHingeColor。您会发现,当您在设计时更改这些属性时,更改将反映在表单设计器中(这很好)。值得注意的是,该控件仅使用 BoardBackColor 显示整行。控件底部的任何剩余空间将使用控件的 BackColor 属性显示。

使用 GDI+ 创建 UserControl

GDI+ 听起来有点吓人。它给人一种您将不得不进行一些底层编程才能使用 GDI+ 的印象。但事实并非如此,因为 .NET Framework 已经将 GDI+ 功能抽象到 System.Drawing 命名空间中,这使得开发人员的生活变得更加轻松和简单。System.Drawing 命名空间的核心是 Graphics 对象。Graphics 具有许多用于绘图的方法。此演示将突出显示在创建您自己的 UserControl 时使用的一些更简单的方法。下面是一个代码片段,它使用了两个简单的图形方法 FillRectangleDrawLine

private void PaintPanel()
{
    //Get the control's Graphics object used to paint
    Graphics g = this.CreateGraphics();
    // Used to paint the row dividers
    Pen dividerPen = new Pen(this.boardRowDividerColor);
    // Used to paint the hinge in the middle of each row
    Pen hingePen = new Pen(this.boardFlickerHingeColor);

    // Paint the control with the board's BoardBackColor
    g.FillRectangle(new SolidBrush(this.boardBackColor), 0, 0,
        	base.Width, this.rowCount * this.rowHeight);

    // Paint row dividers
    for (int i = 0; i <= this.rowCount; i++)
    {
        g.DrawLine(dividerPen, 0, i * this.rowHeight, 
				base.Width, i * this.rowHeight);
    }

    // Paint flicker hinge lines
    for (int i = 0; i < this.rowCount; i++)
    {
        g.DrawLine(hingePen, 0, i * this.rowHeight + (this.rowHeight / 2) + 1,
    	       	base.Width, i * this.rowHeight + (this.rowHeight / 2) + 1);
    }

    // Paint the text values for each row
    for (int i = 0; i < rows.Count; i++)
    {
        PaintRow(new PaintRowParameters(i, Flicker.No, rows[i]));
    }
}

在下一个代码片段中,您还将注意到 DrawRectangleDrawString 方法的使用。所有这些方法都命名得非常好,无需解释,这使得 System.Drawing 命名空间相对直观。同样重要的是 Brushes 的使用。在这种情况下,使用了简单的 SolidBrush,但是可以使用各种 brushes 来真正让您的新控件栩栩如生。还应该注意的是,许多对象需要释放,所以不要忘记在使用完对象后释放它们。

private void PaintCharacter(char c, int colIndex, int rowIndex)
{
    Graphics g = this.CreateGraphics();
    SolidBrush brush = new SolidBrush(ForeColor); //Used to DrawString
    // Used to paint the hinge in the middle of each character
    Pen pen = new Pen(this.boardFlickerHingeColor);

    try
    {
        int x = (this.colWidth * colIndex);
        int y = (this.rowHeight * rowIndex) + 1;
        Rectangle topHalfRect = new Rectangle(x, y, this.colWidth, 
					(this.rowHeight / 2) - 1);
        Rectangle fullRect = new Rectangle(x, y, this.colWidth, this.rowHeight - 1);

        // Just paint the top half of the character first to give
        // the impression that the flap is flicking over
        g.FillRectangle(new SolidBrush(this.boardBackColor), topHalfRect);
        g.DrawString(c.ToString(), this.Font, brush, topHalfRect);
        g.DrawLine(pen, x, y + (this.rowHeight / 2), x +
        	this.colWidth, y + (this.rowHeight / 2));

        // Now paint the whole character
        g.FillRectangle(new SolidBrush(this.boardBackColor), fullRect);
        g.DrawString(c.ToString(), this.Font, brush, fullRect);
        g.DrawLine(pen, x, y + (this.rowHeight / 2), x +
        	this.colWidth, y + (this.rowHeight / 2));
    }
    finally
    {
        g.Dispose();
        brush.Dispose();
        pen.Dispose();
    }
}

如您所见,不需要火箭科学,不需要底层编程。对于我认为相当酷的控件来说,代码相当简单。当然,这只是触及了 GDI+ 可以实现的功能的皮毛,但它表明对于大多数自定义控件,您所需要的只是一些想象力。

有用的提示

在使用 System.Drawing 空间,或者更确切地说是绘制图表时,您会遇到很多 xy 参数。记住什么是 x 和什么是 y 的简单方法就像阅读此页面一样简单。首先您横向阅读 (x),然后向下阅读 (y)。

历史

  • 2009年9月7日:初始版本
© . All rights reserved.