You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET WinForms中CSS3 repeating-linear-gradient()替代方案及填充问题

WinForms旋转重复条纹填充不全的解决办法

问题场景

在WinForms里想实现类似CSS repeating-linear-gradient()的效果,绘制45度角的红、黄、绿循环斑马条纹,但按现有代码实现后,旋转操作导致目标矩形的部分区域没被条纹填满,原代码如下:

private void DrawRepeatingStripes(int degree, int stripeWidth, Color[] colors, Rectangle rect, Graphics graphics)
{
    using (var img = new Bitmap(colors.Length * stripeWidth, rect.Height))
    {
        using (var g = Graphics.FromImage(img))
        {
            for (int i = 0; i < colors.Length; i++)
            {
                // TODO: cache SolidBrush
                g.FillRectangle(new SolidBrush(colors[i]), stripeWidth * i, 0, stripeWidth, rect.Height);
            }
        }
        using (var tb = new TextureBrush(img, WrapMode.Tile))
        {
            using (var myMatrix = new Matrix())
            {
                myMatrix.Rotate(degree);
                graphics.Transform = myMatrix;
                graphics.FillRectangle(tb, rect);
                graphics.ResetTransform();
            }
        }
    }
}

使用示例:

protected override void OnPaintBackground(PaintEventArgs e)
{
    base.OnPaintBackground(e);
    DrawRepeatingStripes(45, 10, new Color[] { Color.Red, Color.Yellow, Color.Green }, e.ClipRectangle, e.Graphics);
}

问题根源

  1. 生成的纹理图高度仅等于目标矩形高度,旋转后纹理的覆盖范围不足以填满原矩形的所有区域——45度旋转后,需要更大的尺寸才能覆盖原矩形的对角线范围
  2. 直接对Graphics应用旋转变换再填充原矩形,会导致纹理坐标偏移,边缘区域无法被覆盖

修复后的代码

private void DrawRepeatingStripes(int degree, int stripeWidth, Color[] colors, Rectangle rect, Graphics graphics)
{
    // 计算目标矩形的对角线长度,确保旋转后纹理能完全覆盖
    float diagonal = (float)Math.Sqrt(rect.Width * rect.Width + rect.Height * rect.Height);
    int textureSize = (int)Math.Ceiling(diagonal);

    // 创建足够大的纹理图,宽度为条纹循环总宽度,高度为对角线长度
    using (var img = new Bitmap(colors.Length * stripeWidth, textureSize))
    {
        using (var g = Graphics.FromImage(img))
        {
            // 绘制水平条纹(后续旋转成目标角度)
            for (int i = 0; i < colors.Length; i++)
            {
                // 缓存Brush,避免频繁创建销毁资源
                using (var brush = new SolidBrush(colors[i]))
                {
                    g.FillRectangle(brush, stripeWidth * i, 0, stripeWidth, textureSize);
                }
            }
        }

        using (var tb = new TextureBrush(img, WrapMode.Tile))
        {
            using (var myMatrix = new Matrix())
            {
                // 将变换中心设置为目标矩形的中心点,避免旋转偏移
                myMatrix.Translate(rect.Left + rect.Width / 2f, rect.Top + rect.Height / 2f);
                myMatrix.Rotate(degree);
                // 平移回原位置,确保纹理对齐目标矩形
                myMatrix.Translate(-(rect.Left + rect.Width / 2f), -(rect.Top + rect.Height / 2f));
                
                tb.Transform = myMatrix;
                // 填充目标矩形,此时纹理已正确旋转并覆盖全部区域
                graphics.FillRectangle(tb, rect);
            }
        }
    }
}

关键修改点

  • 纹理尺寸调整:用目标矩形的对角线长度作为纹理高度,确保旋转后能完全覆盖原矩形区域
  • 变换中心修正:将纹理画笔的变换中心设置为目标矩形的中心,避免旋转后纹理偏移
  • Brush资源优化:在循环内使用using包裹SolidBrush,完成原代码TODO的缓存优化,减少资源消耗

内容的提问来源于stack exchange,提问作者Alexey Y.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 01:50:32