绘制步骤指标作为自定义控件

时间:2013-03-06 14:46:42

标签: c# winforms gdi+

我正在尝试创建步骤指示器控件,该控件将显示当前用户的步骤。 我在运球时发现了一些我想要创造的概念:

dessign

使用非常简单的代码我能够创建如下结果: my result

下面是我的代码:

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace StepIndicator
{
    public class StepIndicatorOne : Control
    {
        public StepIndicatorOne()
        {
            MinimumSize = new Size(300, 50);
            SetStyle(ControlStyles.DoubleBuffer, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            var g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;

            int steps = 3;
            int radiusBig = 20;
            int radiusSmall = 15;
            int bgHeight = 10;

            var gradientRect = new Rectangle(ClientRectangle.X + (ClientRectangle.Width - radiusBig*2)/(steps - 1),
                                             ClientRectangle.Y + ClientRectangle.Height/2 - radiusBig - 1, radiusBig*2, radiusBig*2);

            var lightGrayBrush = new LinearGradientBrush(ClientRectangle, Color.FromArgb(224, 227, 214), Color.LightGray, LinearGradientMode.Vertical);
            var darkGrayBrush = new LinearGradientBrush(gradientRect, Color.DarkGray, Color.Gray, LinearGradientMode.Vertical);
            var lightGreenBrush = new LinearGradientBrush(ClientRectangle, Color.FromArgb(206, 217, 79), Color.FromArgb(191, 201, 82), LinearGradientMode.Vertical);
            var darkGreenBrush = new LinearGradientBrush(ClientRectangle, Color.YellowGreen, Color.ForestGreen, LinearGradientMode.Vertical);

            g.FillRectangle(darkGrayBrush, ClientRectangle.X + radiusBig, ClientRectangle.Y + ClientRectangle.Height/2 - bgHeight/2 - 1,
                            ClientRectangle.Width - radiusBig*2, bgHeight);

            g.FillRectangle(lightGrayBrush, ClientRectangle.X + radiusBig, ClientRectangle.Y + ClientRectangle.Height/2 - bgHeight/2,
                            ClientRectangle.Width - radiusBig*2, bgHeight);

            for (int i = 1; i <= steps; i++)
            {
                g.FillEllipse(darkGrayBrush, ClientRectangle.X + ((ClientRectangle.Width - radiusBig*2)/(steps - 1))*(i - 1),
                              ClientRectangle.Y + ClientRectangle.Height/2 - radiusBig - 1, radiusBig*2, radiusBig*2);
                g.FillEllipse(lightGrayBrush, ClientRectangle.X + ((ClientRectangle.Width - radiusBig*2)/(steps - 1))*(i - 1),
                              ClientRectangle.Y + ClientRectangle.Height/2 - radiusBig, radiusBig*2, radiusBig*2);
            }

            for (int i = 1; i <= steps - 1; i++)
            {
                g.FillEllipse(darkGreenBrush,
                              ClientRectangle.X + ((ClientRectangle.Width - radiusBig*2)/(steps - 1))*(i - 1) + radiusBig - radiusSmall,
                              ClientRectangle.Y + ClientRectangle.Height/2 - radiusSmall - 1, radiusSmall*2, radiusSmall*2);
                g.FillEllipse(lightGreenBrush,
                              ClientRectangle.X + ((ClientRectangle.Width - radiusBig*2)/(steps - 1))*(i - 1) + radiusBig - radiusSmall,
                              ClientRectangle.Y + ClientRectangle.Height/2 - radiusSmall, radiusSmall*2, radiusSmall*2);
            }

        }
    }
}

我的问题是:
是否可以像设计一样创建绿色形状(带有圆圈和孔的绿色条形图)但边框上方有绿色形状?
我可以使用边框绘制带有边框和椭圆的矩形,但是如何将这两个形状组合在一起并在其周围设置边框(将这两个形状合并为一个) - 是我创建复杂路径的唯一选择?

我知道winforms gdi +不能使用内部阴影,但是还有其他一些选项可以创建漂亮的外观效果吗?
现在我用-1偏移和深色绘制相同的形状,但效果不是我想要的效果。

我知道可能最好的解决方案是切换到WPF并在那里绘制,我甚至在SO上发现了样本控制 - Implementing a wizard progress control in WPF但我必须保持在Winforms中

1 个答案:

答案 0 :(得分:1)

使用GraphicsPath作为复杂路径。使用内部阴影的路径渐变。