使用GDI绘制标记(标记)

时间:2014-02-14 16:34:11

标签: c# winforms gdi+ gdi

我正在尝试创建用于显示时间轴的自定义控件 我在网上找到了漂亮的设计:

enter image description here

我开始编码,几分钟后,我有了这个:

enter image description here

正如你可以看到大标记看起来相当不错,但最小标记看起来更好。

我目前负责标记绘制的代码如下所示:

    enum Position
    {
        Left,
        Right
    }

    private void DrawMarker(Graphics gfx, Rectangle Bounds, int CornerRadius, Pen DrawPen, Position direction)
    {
        GraphicsPath gfxPath = new GraphicsPath();
        gfxPath.AddArc(new Rectangle(Bounds.X + Bounds.Width - CornerRadius, Bounds.Y + 0, CornerRadius, CornerRadius), 270, 45); //tr

        if(direction==Position.Right)
            gfxPath.AddArc(new Rectangle(Bounds.X + Bounds.Width - CornerRadius + 40, Bounds.Y + Bounds.Height / 2, CornerRadius, CornerRadius), 315, 90); //right

        gfxPath.AddArc(new Rectangle(Bounds.X + Bounds.Width - CornerRadius, Bounds.Y + Bounds.Height - CornerRadius, CornerRadius, CornerRadius), 45, 45); //br
        gfxPath.AddArc(new Rectangle(Bounds.X + 0, Bounds.Y + Bounds.Height - CornerRadius, CornerRadius, CornerRadius), 90, 90); //bl
        gfxPath.AddArc(new Rectangle(Bounds.X + 0, Bounds.Y + 0, CornerRadius, CornerRadius), 180, 90); //tl
        gfxPath.CloseAllFigures();
        //gfx.FillPath(new SolidBrush(FillColor), gfxPath);
        gfx.DrawPath(DrawPen, gfxPath);
    }

我需要一种方法来改善这些标记的外观 我认为这个问题是右上角和右下角的弧形角度。 我将它们设置为45,但如果标记很小,这看起来很糟糕。

左侧的角度始终为90,但需要计算右侧和上方的角度。

如何修改我的函数以正确计算弧?

1 个答案:

答案 0 :(得分:3)

看起来标签矩形的“鼻子”没有补偿半径大小,这导致“鼻子”向下倾斜:

r.Y + r.Height / 2 - radius / 2

我还将宽度从40缩短到20。

private void DrawMarker(Graphics gfx, Rectangle r, int radius, Pen drawPen, Position direction) {
  using (GraphicsPath gfxPath = new GraphicsPath()) {
    gfxPath.AddArc(new Rectangle(r.X + r.Width - radius, r.Y + 0, radius, radius), 270, 45); //tr
    if (direction == Position.Right) {
      gfxPath.AddArc(new Rectangle(r.X + r.Width - radius + 20, r.Y + r.Height / 2 - radius / 2, radius, radius), 315, 90); //right
    }
    gfxPath.AddArc(new Rectangle(r.X + r.Width - radius, r.Y + r.Height - radius, radius, radius), 45, 45); //br
    gfxPath.AddArc(new Rectangle(r.X + 0, r.Y + r.Height - radius, radius, radius), 90, 90); //bl
    gfxPath.AddArc(new Rectangle(r.X + 0, r.Y + 0, radius, radius), 180, 90); //tl
    gfxPath.CloseAllFigures();
    gfx.DrawPath(drawPen, gfxPath);
  }
}

protected override void OnPaint(PaintEventArgs e) {
  e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
  using (Pen pen = new Pen(Color.DarkGray, 2)) {
    DrawMarker(e.Graphics, new Rectangle(16, 16, 100, 32), 8, pen, Position.Right);
  }
  base.OnPaint(e);
}

结果:

enter image description here