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

一个漂亮的段式 LED 控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (78投票s)

2007年7月17日

CPOL

4分钟阅读

viewsIcon

168575

downloadIcon

10335

本文介绍了构建段式 LED 显示器的实现方式。

Screenshot - screen_shot.png

引言

本文描述了一种构建一个类似闹钟和工业显示器中使用的LED分段显示器的酷炫方法。该控件可用于显示时间、数值甚至一些英文字符。希望它能在硬件模拟器等程序中有所帮助。

背景

在本节中,我想简要介绍一下这个控件背后的想法。在一个7段LED显示器中,一个字符最多由7个段组成,如下图所示。

Figure 1 - 7 segments

图1:分段字符

每个段具有以下属性:段的宽度、段角的斜接率以及段之间的间隔。

Figure 2 - 1 segment

图2:每个段的属性

如果我们像图1所示那样给这7个段编号,那么我们可以用索引来表示不同的字符。例如,字符“1”可以用(2, 3)表示,字符“5”可以用(1, 6, 7, 3, 4)表示。要绘制整个场景,我们首先需要计算绘制特定字符的边界矩形。然后,应该绘制每个指定边界矩形中的段。在指定边界矩形中绘制7段LED字符的算法如图3所示。

Figure 3 - Algorithm

图3:绘制一个字符

使用代码

这个控件非常易于使用。只需在设计模式下将其从工具箱拖到窗体上。然后,在设计器或运行时调整其提供的属性即可修改其外观。属性列表如下表所示。

边框宽度 int 获取或设置控件周围边框的宽度。
BorderColor System.Color 获取或设置控件周围边框的颜色。
HighlightOpaque byte 获取或设置高光的不透明度。0表示高光将以透明结束,而100表示高光将保持其初始透明度。
ShowHighlight bool 获取或设置一个值,指示是否显示控件上的高光区域。如果设置为false,则将忽略HighlightOpaque属性的值。
CornerRadius int 获取或设置控件的圆角半径。如果RoundCorner等于false,则将忽略此属性的值。有效值范围从1到10。
GradientBackground bool 获取或设置背景是否以渐变色填充。
BackColor_1 System.Color 获取或设置第一个背景颜色。如果GradientBackground等于true,则此颜色将是背景矩形顶部的颜色。否则,此颜色将是实心背景颜色。
BackColor_2 System.Color 获取或设置第二个背景颜色。如果GradientBackground等于true,则此颜色将是背景矩形底部的颜色。否则,此颜色将被忽略。
RoundCorner bool 获取或设置边框样式。如果为true,则控件的边框将是圆角矩形。否则,边框是普通矩形。
SegmentIntervalRatio int 获取或设置段间隔比率。此值越大,段之间的间隙越宽。
TextAlignment 对齐 获取或设置文本的对齐样式。
SegmentWidthRatio int 获取或设置段宽度比率。此值越大,段越宽。
TotalCharCount int 获取或设置要显示的字符总数。如果显示的文本中包含的字符数大于此值,则显示的字符将被截断。
BevelRate float 获取或设置每个段的斜接率。有关更多信息,请参阅图2。
FadedColor System.Color 获取或设置渐隐背景字符的颜色。
文本 字符串 获取或设置控件的文本。

关注点

表示级别的控件可能会执行大量的绘制操作。大多数时候,当控件的某个属性发生更改时,控件都需要重新绘制。如果控件的多个属性在短时间内连续更改,可能会导致多次无效化。为了避免多次绘制,我们可以在控件中实现ISupportInitialize接口。首先,我们在BeginInit()方法中设置一个成员变量。

private bool m_bIsInitializing = false;
void ISupportInitialize.BeginInit()
{
    m_bIsInitializing = true;
}

然后,我们按以下方式重写我们的属性:

public Color FadedColor
{
    get
    {
        return m_colFadedColor;
    }
    set
    {
        if (m_colFadedColor == value)
        return;
        m_colFadedColor = value;
        // check if the control is in initializing mode
        if (!m_bIsInitializing)
        {
            Invalidate();
        }
    }
}

最后,在EndInit()方法中,我们关闭初始化模式并重新绘制控件。

void ISupportInitialize.EndInit()
{
    m_bIsInitializing = false;
    Invalidate();
}

现在我们可以使用批量初始化来防止控件的连续绘制。

((System.ComponentModel.ISupportInitialize)mycontrol).BeginInit();
mycontrol.BackColor = System.Drawing.Color.Transparent;
mycontrol.BackColor_1 = System.Drawing.Color.Black;
mycontrol.BackColor_2 = System.Drawing.Color.Transparent;
mycontrol.BevelRate = 0.5F;
mycontrol.BorderColor = System.Drawing.Color.White;
mycontrol.FadedColor = System.Drawing.Color.Black;
((System.ComponentModel.ISupportInitialize)mycontrol).EndInit();

历史

  • 2007年7月15日 -- 发布原始版本
  • 2007年7月20日 -- 更新了下载内容
  • 2008年5月7日 -- 更新了下载内容
    1. 用户现在可以开启平滑绘制模式,使控件看起来更好
    2. 支持斜体文本样式
    3. 修复了一个bug:如果边界矩形是常规矩形,则底部和右侧边界将不可见
  • 2008年5月12日 -- 更新了下载内容
    1. 当控件获得焦点时,用户可以复制控件上的文本。
    2. 当控件获得和失去焦点时,边框的颜色会改变(由用户定义)。
    3. 修复了一个bug:当边界是规则矩形时,抗锯齿效果会消失。
© . All rights reserved.