2

ユーザーが現在どのステップにいるかを示すステップインジケーターコントロールを作成しようとしています。ドリブルで作成したいコンセプトを見つけました:

デザイン

非常に単純なコードを使用して、次のような結果を作成できました。 私の結果

以下は私のコードです:

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);
            }

        }
    }
}

私の質問は次のとおり
です。設計どおりの緑色の形状(円と穴が1つある緑色のバー)を作成できますが、その上に境界線がありますか?
境界線で四角形を描画し、その上に境界線で楕円を描くことができますが、これらの 2 つの形状を組み合わせてその周りに境界線を付けるにはどうすればよいですか (これらの 2 つの形状を 1 つに結合する) - 複雑なパスを作成する唯一のオプションですか?

winforms gdi+ はインナー シャドウを使用できないことはわかっていますが、インナー グローに似た見栄えの良い効果を作成する他のオプションはありますか?
今、私は -1 のオフセットとより暗い色で同じ形を描いていますが、効果は私が望むものではありません。

おそらく最善の解決策は、WPFに切り替えてそこに描画することであることを知っています.SOでサンプルコントロールを見つけました-WPFでウィザードの進行状況コントロールを実装していますが、Winformsにとどまる必要があります

4

1 に答える 1

1

複雑なパスには GraphicsPath を使用します。内側の影にはパス グラデーションを使用します。

于 2013-06-18T21:04:34.903 に答える