Home > Mobile >  Replacement for CSS3 function repeating-linear-gradient() in .NET (WinForms)
Replacement for CSS3 function repeating-linear-gradient() in .NET (WinForms)

Time:12-30

Is there any replacement (analogue) for CSS3 function repeating-linear-gradient() in .NET (WinForms, not WPF)? I need to paint repeating "zebra stripes" (e.g. red, blue, green, red, blue, green, ...) at an angle 45 degrees.

UPD: Following Jimi's advice I managed to solve the problem only partially:

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

Usage (in some form's code):

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

The problem is that rotation is... well, a rotation, so part of rect is filled with stripes and part is empty. Have no idea how to solve it :(

CodePudding user response:

An example about using a Linear Repeating Gradient

Since the ColorBands property is bindable, you can use data bindings to perform actions, when a ColorBand object is added or removed and also bind the collection to a Controls, as shown in the animation:

public partial class SomeForm : Form {

    LinearRepeatingGradient gradient = new();

    public SomeForm()
    {
        InitializeComponent();
        [DataGridView].DataSource = gradient.ColorBands;
        gradient.ColorBands.ListChanged  = (s, e) => someControl.Invalidate();
    }

    private void someControl_Paint(object sender, PaintEventArgs e) => gradient.Fill(e.Graphics);

As a consequence, when you add a new ColorBand (or remove it), the internal collection changes and the Control used as canvas is invalidated, showing the new fill:

gradient.ColorBands.Add(new ColorBand(Color.Red, 45f));

The RotationAngle property doesn't use data bindings, so you have to invalidate the canvas manually when you change it. You can of course change that and make this property bindable:

gradient.RotationAngle = 215f;
someControl.Invalidate();
  • Related