I'm presently in the design stage of a huge smart-client application, with tons of stunning UIs. Looking at the UI designs, it quickly became obvious that I'd have to spend a lot of time writing code to paint gradient fills, which seem to be quite hot among graphic designers these days. And it's not hard to understand why; the difference they make to a UI is quite spectacular.
So faced with the potential nightmare of having to paint everything from a simple
Label to a complex container control, I started on a small GUI library, which I code named Inferno. The idea was to build several controls inherited from the classes in
System.Windows.Forms, and to attach design-time configurable gradient fills. So for instance, instead of the usual
BackColor property, a
Label would have a
BackGraident property. Well hopefully, in the near future I'd be able to post the entire library here. Keep your fingers crossed…
So this article is about the very first widget I cooked up. Although, it was originally built to be used as a
UITypeEditor for my
Gradient class, I'm sure many people could find a use for it in any form of graphics applications that they maybe building.
How it ticks
GradientBuidler class is a custom painted control which is split horizontally into two rectangular areas, called the
gradientBarRect and the
The marker strip area is where the user can insert new color steps on to the gradient. He could basically double click on any point right below the gradient preview, to insert a new marker (which defaults to the exact color of the gradient just above it). The markers, other than the start and end markers could be moved along the marker strip to fine tune the gradient.
The preview of the gradient is painted on to the
gradientBarRect in a discretionary manner. When the gradient is changed, the new gradient is painted on to a
Bitmap object which is then painted on to the gradient bar area. The
Bitmap object serves as a cached snapshot of the gradient, greatly improving the performance of the paint operation when the control has to repaint itself. Incidentally, this behavior was not present in my actual
UITypeEditor as it would only need to be displayed for a very short amount of time.
The code also includes the TypeEditor developed by Emmanuel Tissandier for displaying the color picker.
Using the gradient editor
The gradient editor is set to expose an object of type
Gradient class contains several methods that you can use while performing common fill operations:
public void FillRectangle( Graphics g, Rectangle rect )
public void FillRegion( Graphics g, Region rgn )
public void FillPath( Graphics g, GraphicsPath path )
If on the other hand you require more flexibility, you can obtain a handle to either a
LinearGradientBrush or a
PathGradientBrush object by using,
public PathGradientBrush GetPathGradientBrush( GraphicsPath path )
public LinearGradientBrush GetLinearGradientBrush(Rectangle rect)
You would then of course be responsible for disposing of the brush once you're done.
GradientChanged event of the
GradientEditor to redraw your graphics when the user makes changes to the
Gradient. By setting the
SilentMarkers property to
false (default) you could make the control fire this event even as a marker is being dragged.
A word about the demo
The demo app I've included is perhaps too simple for anybody's liking. Painting on a
Panel by handling its
Paint event is not the most optimal way to go. I've only done it to keep things as simple as possible. If you are writing a real graphics app, I recommend that you use one of the many great canvas classes CodeProject seems to have.