尝试在C#中的控件边缘绘制类似Dropshadow的渐变

时间:2015-07-11 06:04:42

标签: c# winforms graphics system.drawing

我正在尝试创建一个函数,它会在控件的任何给定边上生成类似Drophadow的渐变。我对System.Drawing并不是非常熟悉,但之前曾使用过它,并利用这种经验来尝试做到这一点。我基本上是通过一个像素的线(通过使用名为length的值的for循环来绘制渐变,一个像素的线来确定线的数量),它会根据alpha值进行更改我正在使用的pen

问题无论是我错误地计算了如何获取下一行的alpha值,或者我错误地使用System.Drawing。我想可能是后者;无论是使用bitmap还是设置Graphics graphics = this.CreateGraphics()中的graphics,我都无法弄清楚如何生成bitmap我要生成的内容。

我不确定如何分解这个问题的代码,但无论如何它都是一个相对较短的函数。有关函数如何工作的更多详细信息,请参阅文档。

/// <summary>
/// Generates a simple drop shadow at any rectangular angle along the edge of a control of choice.
/// </summary>
/// <param name="startAlpha">The starting alpha (transparency) value of the gradient of the shadow.</param>
/// <param name="fourthsRotationDirection">The rotation (in 90 degree values) of the shadow.</param>
/// <param name="control">The control to be given a shadow.</param>
/// <param name="length">The length or depth of the shadow.</param>
/// <param name="clearShadow">Determines whether or not the function should clear all graphics to rid of any preexisting shadows, mostly for regeneration purposes.</param>
void DropShadowGenerator(int startAlpha, FourthsRotationDirection fourthsRotationDirection, Control control, int length, bool clearShadow)
{
    PictureBox image = new PictureBox();
    image.Location = new Point(0, 0);
    image.Size = this.Size;
    this.Controls.Add(image);

    Bitmap bmp = new Bitmap(this.Width, this.Height);
    Graphics graphics = Graphics.FromImage(bmp);
    Pen pen = (fourthsRotationDirection == FourthsRotationDirection.Zero || fourthsRotationDirection == FourthsRotationDirection.OneEighty) ? new Pen(Color.FromArgb(startAlpha), control.Height) : new Pen(Color.FromArgb(startAlpha), control.Width);
    Point startPoint = new Point();
    Point endPoint = new Point();
    float shadowFactor = 255 / length;
    float currentAlpha = startAlpha;

    if (clearShadow)
    {
        graphics.Clear(Color.Transparent);
    }

    if (fourthsRotationDirection == FourthsRotationDirection.Zero)
    {
        startPoint = new Point(control.Location.X + control.Width, control.Location.Y);
        endPoint = new Point(startPoint.X, startPoint.Y + control.Height);
    }
    else if (fourthsRotationDirection == FourthsRotationDirection.OneEighty)
    {
        startPoint = new Point(control.Location.X, control.Location.Y);
        endPoint = new Point(startPoint.X, startPoint.Y + control.Height);
    }
    else if (fourthsRotationDirection == FourthsRotationDirection.Ninety)
    {
        startPoint = new Point(control.Location.X, control.Location.Y);
        endPoint = new Point(startPoint.X + control.Width, startPoint.Y);
    }
    else if (fourthsRotationDirection == FourthsRotationDirection.TwoSeventy)
    {
        startPoint = new Point(control.Location.X, control.Location.Y + control.Height);
        endPoint = new Point(startPoint.X + control.Width, startPoint.Y);
    }

    for (int i = 1; i <= length; i++)
    {            
        graphics.DrawLine(pen, startPoint, endPoint);

        currentAlpha = currentAlpha - shadowFactor;
        pen.Color = Color.FromArgb((int)currentAlpha, Color.Black);

        switch (fourthsRotationDirection)
        {
            case FourthsRotationDirection.Zero:
                startPoint = new Point(startPoint.X++, startPoint.Y);
                endPoint = new Point(endPoint.X++, endPoint.Y);
                break;

            case FourthsRotationDirection.OneEighty:
                startPoint = new Point(startPoint.X--, startPoint.Y);
                endPoint = new Point(endPoint.X--, endPoint.Y);
                break;

            case FourthsRotationDirection.Ninety:
                startPoint = new Point(startPoint.X, startPoint.Y--);
                endPoint = new Point(endPoint.X, endPoint.Y--);
                break;

            case FourthsRotationDirection.TwoSeventy:
                startPoint = new Point(startPoint.X, startPoint.Y++);
                endPoint = new Point(endPoint.X, endPoint.Y++);
                break;
        }
    }

    image.Image = bmp;
}

如何在表单上显示?如前所述,我只是错误地使用System.Drawing,还是我的渐变生成本身不正确?

1 个答案:

答案 0 :(得分:0)

您的主要问题是计算新坐标的方式:

startPoint = new Point(startPoint.X++, startPoint.Y);
endPoint = new Point(endPoint.X++, endPoint.Y);

这实际上并没有改变坐标,因为你首先分配值然后再增加它。 尝试:

startPoint = new Point(++startPoint.X, startPoint.Y);
endPoint = new Point(++endPoint.X, endPoint.Y);

或者,我发现它更具可读性:

startPoint = new Point(startPoint.X+1, startPoint.Y);
endPoint = new Point(endPoint.X+1, endPoint.Y);

或者,如果没有创建新的Point,那么你可以做你做的事情:

startPoint.X++;
endPoint.X++;