透明背景色的可定制移动文字的Label控件

来源:互联网 发布:kali linux fcitx安装 编辑:程序博客网 时间:2024/05/18 03:21
透明控件有十二个增加的属性

# BackColor - 控件的背景色
# Opacity - 0到255,混合控件背景的alpha值
# Radius - 边框圆角半径
# ShapeBorderStyle - 控件外边框的风格
# BorderColor - 控件外边框的颜色
# Caption - 控件文字
# Font - 字体
# Forecolor - 字体颜色
# TextAlign - 对齐方式(只在字体不移动情况下起作用)
# Moving - 移动字体(None, RightToLeft, DownToUp, LeftToRight, UpToDown).
# MovingActive - 字体是否开始移动
# DimmedColor - 当鼠标移动到字体上的字体颜色
透明背景色的可定制移动字体Label控件

OnPaint 方法调用了三个简单的方法:DrawBorder, DrawLabelBackground, DrawText.
Code:
protected override void OnPaint(PaintEventArgs e)
{
    SmoothingMode sm = e.Graphics.SmoothingMode;
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    if (_borderStyle == ShapeBorderStyles.ShapeBSFixedSingle)
        DrawBorder(e.Graphics);
    DrawLabelBackground(e.Graphics);
    DrawText(e);
    e.Graphics.SmoothingMode = sm;
}



DrawBorder 方法:

Code:
private void DrawBorder(Graphics g)
{
    Rectangle rect = this.ClientRectangle;
    rect.Width--;
    rect.Height--;
    using (GraphicsPath bp = GetPath(rect, _radius))
    {
        using (Pen p = new Pen(_borderColor))
        {
            g.DrawPath(p, bp);
        }
    }
}



DrawLabelBackground 方法:

Code:
private void DrawLabelBackground(Graphics g)   
{
    Rectangle rect = this.ClientRectangle;
    iRect = rect;
    rect.X++;
    rect.Y++;
    rect.Width -= 2;
    rect.Height -= 2;
    using (GraphicsPath bb = GetPath(rect, _radius))
    {
        using (Brush br = new SolidBrush(
            Color.FromArgb(_opacity, _backColor)))
        {
            g.FillPath(br, bb);
        }
    }
}



DrawBorder DrawLabelBackground调用的GetPath 方法:

Code:
protected GraphicsPath GetPath(Rectangle rc, int r)
//  Build the path with the round corners in the rectangle
//  r is the radious of rounded corner.
{
    int x = rc.X, y = rc.Y, w = rc.Width, h = rc.Height;
    r = r << 1;
    GraphicsPath path = new GraphicsPath();
    if (r > 0)
        //  If the radious of rounded corner is greater than one side then
        //  do the side rounded
    {
        if (r > h) { r = h; };                           //Rounded
        if (r > w) { r = w; };                           //Rounded
        path.AddArc(x, y, r, r, 180, 90);                //Upper left corner
        path.AddArc(x + w - r, y, r, r, 270, 90);        //Upper right corner
        path.AddArc(x + w - r, y + h - r, r, r, 0, 90);  //Lower right corner
        path.AddArc(x, y + h - r, r, r, 90, 90);         //Lower left corner
        path.CloseFigure();
    }
    else
        // If the radious of rounded corner is zero then the path is
        // a rectangle
    {
        path.AddRectangle(rc);
    }

    return path;
}



DrawText 方法:

Code:
protected void DrawText(PaintEventArgs pe)
{
    //This is a workaround to get MeasureString to work properly
    //pe.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
    SizeF sz = pe.Graphics.MeasureString(_text, base.Font);
    switch (_moving)
    {
    case MoveType.None:
        NoMove();
        break;
    case MoveType.RightToLeft:
        MoveRightToLeft();
        break;
    case MoveType.DownToUp:
        MoveDownToUp();
        break;
    case MoveType.LeftToRight:
        MoveLeftToRight();
        break;
    case MoveType.UpToDown:
        MoveUpToDown();
        break;
    }
    //Rectangle bounds for the text
    txtRect = new Rectangle(this.pointX, this.pointY,
        (int)sz.Width + 1, (int)sz.Height);
    //If the mouse is passing over the text it is selected and will be dimmed
    //otherwise nothing.
    Brush brText = new SolidBrush(base.ForeColor);
    Brush brTextDimmed = new SolidBrush(_dimmedColor);
    if (_isSelected)
        pe.Graphics.DrawString(_text,
        base.Font,
        brTextDimmed,
        txtRect);
    else
        pe.Graphics.DrawString(_text,
        base.Font,
        brText,
        txtRect);
}



针对不同移动类型的NoMove(), MoveRigntToLeft(), MoveDownToUp(), MoveLeftToRight() 和 MoveUpToDown()方法。

Code:
protected void NoMove()
{
    //Align text
    switch (_textAlign)
    {
    case TextAlignment.Left:
        pointX = (int)this.iRect.X;
        break;
    case TextAlignment.Center:
        pointX = (this.iRect.Width - this.txtRect.Width) / 2;
        break;
    case TextAlignment.Right:
        pointX = (this.iRect.Width - this.txtRect.Width);
        break;
    }
    pointY = (this.iRect.Height - this.txtRect.Height) / 2;
}
protected void MoveRightToLeft()
{
    if (pointX < -this.txtRect.Width)
    { pointX = this.iRect.X + this.iRect.Width; }
    else
    { pointX -= 2; }
    pointY = (this.iRect.Height - this.txtRect.Height) / 2;
}
protected void MoveDownToUp()
{
    pointX = (this.iRect.Width - this.txtRect.Width) / 2;
    if (pointY < -this.txtRect.Height)
    { pointY = (int)this.iRect.Y + this.iRect.Height; }
    else
    { pointY -= 2; }
}
protected void MoveLeftToRight()
{
    if (pointX > this.iRect.X + this.iRect.Width)
    { pointX = this.iRect.X - this.txtRect.Width; }
    else
    { pointX += 2; }
    pointY = (this.iRect.Height - this.txtRect.Height) / 2;
}
protected void MoveUpToDown()
{
    pointX = (this.iRect.Width - this.txtRect.Width) / 2;
    if (pointY > this.iRect.Y + this.iRect.Height)
    { pointY = (int)this.iRect.Y - this.iRect.Height; }
    else
    { pointY += 2; }
}



鼠标经过控件上文字的触发:

Code:
protected override void OnMouseEnter(EventArgs e)
{
    base.OnMouseEnter(e);
    _isSelected = true;
    this.Invalidate();
}
protected override void OnMouseLeave(EventArgs e)
{
    base.OnMouseLeave(e);
    _isSelected = false;
    this.Invalidate();
}



组件还使用了一个定时器更新或失效Draw 事件OnPaint.

Code:
private void timer1_Tick(object sender, System.EventArgs e)
{
    this.Update();
    this.Invalidate();
}
 
原创粉丝点击