Home

GDI+ Brushes: Linear Gradient Brushes

     

Introduction

A gradient brush resembles a solid brush in that it is color-based. Unlike a solid brush, a gradient brush uses two colors. Its main characteristic is that, when used, one color is applied on one side and the other color is applied to the other side. In between, both colors merge to create a transition or fading effect.

There are two types of gradient brushes: linear and path.

Linear Brushes

A linear gradient is used to apply two colors in a closed shape but from one side of the shape, such as the left, to the other opposite side of the shape, such as the right.

To support linear gradient brushes, the .NET Framework provides the LinearGradientBrush class defined in the System.Drawing.Drawing2D namespace. To specify the starting and the end points inside of the shape that you want to fill, you can use one of the following constructors:

public LinearGradientBrush(Point point1, 
			Point point2, 
			Color color1, 
			Color color2);
public LinearGradientBrush(PointF point1,
			PointF point2, 
			Color color1, 
			Color color2);

The first argument, point1, is the point where the drawing would start. The third argument, color1, is the color that would be applied from that point. The second argument, point2, is the point where the drawing would end by applying the color specified by the fourth argument, color2.

Here is an example:

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

public class Exercise : Form
{
    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        Paint += new PaintEventHandler(Exercise_Paint);
    }

    private void Exercise_Paint(object sender, PaintEventArgs e)
    {
        LinearGradientBrush lgb =
        new LinearGradientBrush(new Point(20, 20),
                                new Point(450, 20),
                                Color.DarkGreen,
                                Color.LightBlue);
        e.Graphics.FillRectangle(lgb, 20, 20, 430, 180);
    }
}

public class Program
{
    public static int Main()
    {
        Application.Run(new Exercise());

        return 0;
    }
}

Gradient Brush

By default, the linear gradient brush fills its gradient based on a horizontal line. If you want the color merge to use a different orientation, such as vertical or diagonal, you can use one of the following constructors:

public LinearGradientBrush(Rectangle rect, 
			Color color1, 
			Color color2, 
			LinearGradientMode factor);
public LinearGradientBrush(RectangleF rect, 
			Color color1, 
			Color color2, 
			LinearGradientMode factor);

The first argument, rect, is the rectangle inside of which the colors would be applied. The second argument, color1, is the color that would be applied from a starting point. The second argument, color2, is the color that would be applied at the other end. The factor argument is used to determine the orientation of the merging colors. It has the following members:

Vertical: The first color, color1,  is applied to the top section of the rect argument. The second color, color2,  is applied to the bottom section of the rect argument:

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

public class Exercise : System.Windows.Forms.Form
{
    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        Text = "Gradient Brushes";
        Paint += new PaintEventHandler(PaintForm);
    }

    void PaintForm(object sender, PaintEventArgs e)
    {
        Rectangle rect = new Rectangle(10, 10, 470, 300);
        LinearGradientBrush lgb =
         new LinearGradientBrush(rect,
                                       Color.DarkRed,
                                   Color.White,
           LinearGradientMode.Vertical);
        e.Graphics.FillRectangle(lgb, 10, 10, 450, 280);
    }
}

public class Program
{
    static int Main()
    {
        System.Windows.Forms.Application.Run(new Exercise());
        return 0;
    }
}

Linear Brush

Horizontal: The first color, color1,  is applied to the left section of the rect argument. The second color, color2,  is applied to the right section of the rect argument

Linear Brush

BackwardDiagonal: The first color, color1,  is applied to the top-right corner of the rect argument. The second color, color2,  is applied to the bottom-left corner of the rect argument:

Gradient Brush

ForwardDiagonal: The first color, color1,  is applied to the top-left corner of the rect argument. The second color, color2, is applied to the bottom-right corner of the rect argument:

The constructor used to produce the above orientation has the limitation that it provides only four options. If you want, you can apply any angular merge as you see fit. To do this, you can use one of the following constructors:

public LinearGradientBrush(Rectangle rect,
			Color color1,
			Color color2, 
			float angle);
public LinearGradientBrush(RectangleF rect, 
			Color color1, 
			Color color2, 
			float angle);

The first argument, rect, is the rectangle inside of which the colors would be applied. The last argument, angle, is an angle measured clockwise, that will specify the orientation of the merging colors The second argument, color1, is the color that would be applied from the starting point. The second argument, color2, is the color that would be applied at the other end. Here is an example:

private void Exercise_Paint(object sender, PaintEventArgs e)
{
        Rectangle rect = new Rectangle(10, 10, 470, 300);
        LinearGradientBrush lgb = new LinearGradientBrush(rect,
	                                              Color.DarkRed,
	                                              Color.White,
       	                                              -65.24F);
        e.Graphics.FillRectangle(lgb, 10, 10, 450, 280);
}

Linear Brush

ApplicationApplication: Using a Linear Gradient Brush

  1. Reopen the YearlySales2 project and change the Paint event of the form as follows:
    private void btnGenerate_Click(object sender, EventArgs e)
    {
            // Retrieve the values of the current year's sales
            int curQtr1 = 0;
            int curQtr2 = 0;
            int curQtr3 = 0;
            int curQtr4 = 0;
    
            try
            {
                    curQtr1 = int.Parse(txtCurrentQtr1.Text) / 100;
            }
            catch (FormatException)
            {
                    MessageBox.Show("Invalid Value");
            }
    
            try
            {
                    curQtr2 = int.Parse(txtCurrentQtr2.Text) / 100;
            }
            catch (FormatException)
            {
                    MessageBox.Show("Invalid Value");
            }
    
            try
            {
                    curQtr3 = int.Parse(txtCurrentQtr3.Text) / 100;
            }
            catch (FormatException)
            {
                    MessageBox.Show("Invalid Value");
            }
    
            try
            {
                    curQtr4 = int.Parse(txtCurrentQtr4.Text) / 100;
            }
            catch (FormatException)
            {
                    MessageBox.Show("Invalid Value");
            }
    
            // Create an array of Rectangle objects for the current year
            Rectangle[] rectCurrentYear =
            {
                    new Rectangle(this.txtCurrentQtr1.Left+20,
    			                  380-curQtr1, 40, curQtr1),
                    new Rectangle(this.txtCurrentQtr2.Left+20,
    			                   380-curQtr2, 40, curQtr2),
    		        new Rectangle(this.txtCurrentQtr3.Left+20,
    			                  380-curQtr3, 40, curQtr3),
    		        new Rectangle(this.txtCurrentQtr4.Left+20,
    			                  380-curQtr4, 40, curQtr4)
            };
    
            // Retrieve the values of last year's sales
            int prvQtr1 = 0;
            int prvQtr2 = 0;
            int prvQtr3 = 0;
            int prvQtr4 = 0;
    
            try
            {
                    prvQtr1 = int.Parse(txtPreviousQtr1.Text) / 100;
            }
            catch (FormatException)
            {
                    MessageBox.Show("Invalid Value");
            }
    
            try
            {
                    prvQtr2 = int.Parse(txtPreviousQtr2.Text) / 100;
            }
            catch (FormatException)
            {
                    MessageBox.Show("Invalid Value");
            }
    
            try
            {
                    prvQtr3 = int.Parse(txtPreviousQtr3.Text) / 100;
            }
            catch (FormatException)
            {
                    MessageBox.Show("Invalid Value");
            }
    
            try
            {
                    prvQtr4 = int.Parse(txtPreviousQtr4.Text) / 100;
            }
            catch (FormatException)
            {
                    MessageBox.Show("Invalid Value");
            }
    
            // Create an array of Rectangle objects for the previous year
            Rectangle[] rectPreviousYear =
            {
                    new Rectangle(this.txtPreviousQtr1.Left+30,
    			                  380-prvQtr1, 40, prvQtr1),
     		        new Rectangle(this.txtPreviousQtr2.Left+30,
    			                  380-prvQtr2, 40, prvQtr2),
    	            new Rectangle(this.txtPreviousQtr3.Left+30,
    			                  380-prvQtr3, 40, prvQtr3),
    		        new Rectangle(this.txtPreviousQtr4.Left+30,
    			                  380-prvQtr4, 40, prvQtr4)
            };
    
            // In case the user has changed the values, erase the previous chart
            graphDrawingArea.Clear(this.BackColor);
    
            Rectangle rect = new Rectangle(10, 190, 300, 210);
            LinearGradientBrush linGradBrush =
    		new LinearGradientBrush(rect,
    		  Color.FromArgb(204, 102, 0),
    		  Color.AntiqueWhite,
    		          LinearGradientMode.Vertical);
            graphDrawingArea.FillRectangle(linGradBrush, rect);
            graphDrawingArea.DrawRectangle(new Pen(Color.Black), rect);
    
            HatchBrush brushDiagCross =
                 new HatchBrush(HatchStyle.DiagonalCross,
                          Color.White, Color.Blue);
            HatchBrush brushDotDiamond =
                 new HatchBrush(HatchStyle.DottedDiamond,
                          Color.Fuchsia, Color.Brown);
    
            // Draw the chart for the previous year first to send it back
            graphDrawingArea.FillRectangles(brushDiagCross,
                                 rectPreviousYear);
            graphDrawingArea.DrawRectangles(new Pen(Color.Blue),
                                 rectPreviousYear);
            // Draw the chart for the current year in front
            graphDrawingArea.FillRectangles(brushDotDiamond,
                                 rectCurrentYear);
            graphDrawingArea.DrawRectangles(new Pen(Color.Red),
                                 rectCurrentYear);
    
            // Draw the small rectangles of the legend
            graphDrawingArea.FillRectangle(brushDotDiamond,
                                this.lblCurYear.Left - 30,
                                this.lblCurYear.Top, 20, 14);
            graphDrawingArea.DrawRectangle(new Pen(Color.Red),
                                this.lblCurYear.Left - 30,
                                this.lblCurYear.Top, 20, 14);
            graphDrawingArea.FillRectangle(brushDiagCross,
                                this.lblLastYear.Left - 30,
                                this.lblLastYear.Top, 20, 14);
            graphDrawingArea.DrawRectangle(new Pen(Color.Blue),
                                this.lblLastYear.Left - 30,
                                this.lblLastYear.Top, 20, 14);
    
            graphDrawingArea.DrawRectangle(new Pen(Color.Black),
                                25, 380, Width - 220, 1);
            Invalidate();
    }
  2. Execute the application to test it:
     
  3. After using the form, close it

Path Gradient Brushes

The second type of gradient brush available is referred to as path gradient. This brush is applied on a path created by connecting a series of points to get a closed shape.  The interior of the shape can then be filled as a gradient.

To support path brushes, the .NET Framework provides the PathGradientBrush from the System.Drawing.Drawing2D namespace. Two of the constructors of this class are:

public PathGradientBrush(Point points[]);
public PathGradientBrush(PointF points[]);

The argument passed to this constructor is an array of type Point. Here is an example:

private void Exercise_Paint(object sender, PaintEventArgs e)
{
        Point[] ptGraph =
        {
            new Point(10, 10),
            new Point(450, 10),
            new Point(450, 250),
            new Point(10, 250)
        };

        PathGradientBrush pgb = new PathGradientBrush(ptGraph);
        e.Graphics.FillRectangle(pgb, 10, 10, 450, 280);
}

Path Gradient Brush

 
 

Home Copyright © 2010-2011 C# Key