【问题标题】:draw step indicator as custom controll将步骤指示器绘制为自定义控件
【发布时间】:2013-06-19 05:04:34
【问题描述】:

我正在尝试创建步数指示器控件,该控件将显示用户当前所在的步数。 我在 dribble 上发现了一些我想创建的概念:

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

下面是我的代码:

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

【问题讨论】:

  • 将这些创建为图像(至少是复杂部分)并绘制图像可能会更容易。
  • @LarsTech - 我正在考虑这个问题,但是对于图像,我将无法在不更改图像的情况下自定义控件的外观。我想创建一个带有一些配置选项的控件(渐变的颜色、圆的半径、水平条的高度),这些设置的图像毫无价值。我想尝试用代码创建整个控件,图像是我最后的选择。感谢您的建议,但现在我将继续使用代码绘图 :)
  • 尝试使用具有透明背景的 png 并仅绘制带有边框的复选标记。您发布的那些复选标记示例似乎是大小不同的两张不同图像。
  • @LarsTech - 复选标记将是一个图像。我计划添加为每个步骤指定图标作为配置选项的功能,但我想用代码绘制其他所有内容。我现在最大的问题是如何将水平条和灰色圆圈组合在一起,以便将边框作为单个形状围绕它绘制,而不是围绕每个形状(希望我的描述有意义:))

标签: c# winforms gdi+


【解决方案1】:

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

【讨论】:

  • 能否请您发布一个简单的使用示例?我试过使用 PraphicsPath 但没有任何运气,我在画角时遇到问题(上面有线和圆,圆必须是圆的,但线和圆之间的角必须是,嗯..一个角:))
  • 您可以将直线和圆弧添加到 GraphicsPath。圆角是弧线。我没有任何示例代码;通常我会使用 VG.net 来完成这样的任务。
  • VG.net 看起来不错,但对于将创建应用程序作为业余爱好和学校项目的人来说,它的成本太高了。除此之外,我还计划创建我的组件并将其作为开源发布。我将尝试通过代码创建该路径。
猜你喜欢
  • 2023-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-09
  • 2013-05-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多