我正在尝试创建步骤指示器控件,该控件将显示当前用户的步骤。 我在运球时发现了一些我想要创造的概念:
使用非常简单的代码我能够创建如下结果:
下面是我的代码:
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中
答案 0 :(得分:1)
使用GraphicsPath作为复杂路径。使用内部阴影的路径渐变。