|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThere are a lot of great Vista-style controls written in .NET. So this is yet one more, a command-link button. I am a fan of creating custom controls from scratch rather than depending on the OS drawing libraries. Thus, our CommandLink is drawn entirely with C# code, making it compatible with older versions of Windows. Goal of the CommandLinkWhen I set out to write the control, I decided I wanted a CommandLink that had that Vista-style feel to it, but that did replicate default Command-Links exactly. So, I wrote a simple goal list of which elements to include:
Rounded RectanglesBefore drawing the actual control, first, we need a function to draw rounded rectangles. Since the button will need to outline and fill the round rectangle, it is easiest to write a function that returns a private static GraphicsPath RoundedRect(int width, int height, int radius)
{
RectangleF baseRect = new RectangleF(0, 0, width, height);
float diameter = radius * 2.0f;
SizeF sizeF = new SizeF(diameter, diameter);
RectangleF arc = new RectangleF(baseRect.Location, sizeF);
GraphicsPath path = new GraphicsPath();
// top left arc
path.AddArc(arc, 180, 90);
// top right arc
arc.X = baseRect.Right - diameter;
path.AddArc(arc, 270, 90);
// bottom right arc
arc.Y = baseRect.Bottom - diameter;
path.AddArc(arc, 0, 90);
// bottom left arc
arc.X = baseRect.Left;
path.AddArc(arc, 90, 90);
path.CloseFigure();
return path;
}
Drawing ElementsSo, let’s break down the visual elements of the CommandLink. The only two complicated states are the Hover and the Down state. Hover
The part that makes the button pop-up is a simple white gradient that goes three-fourths of the way down the button’s height. Due to the way the WrapMode.TileFlipX
Next comes the outline. It is a 3 radius rounded rectangle generated with the above function. The color can either be
Then, we need an inside outline. This will be 2 radius instead, and is positioned at coordinates We put it together by drawing them in order, and we get something like this:
Down
The background this time is solid, and once again, can either be a system color (
The outline will be the same as before, except the color will be darker,
Lastly, the inner outline too will only change colors to a dark color (to give a shadow effect). The final down state:
HighlightThe user should be able to tell when the CommandLink is selected, even if it was done with Tab. To highlight a selected CommandLink, we draw only an inner outline with the color Foreground – Image and TextThe foreground elements will be the same for any state of the button. There is actually nothing special to drawing the text and the image. The description text will always be three sizes smaller than the header text. The font can be changed, but the default one is Tahoma. To center the combined sizes of the header and the description text, go with: SizeF headerLayout = g.MeasureString(headerText, this.Font);
SizeF descriptLayout = g.MeasureString(descriptionText, descriptFont);
//Merge the two sizes into one big rectangle
Rectangle totalRect = new Rectangle(0, 0,
(int)Math.Max(headerLayout.Width,
descriptLayout.Width),
(int)(headerLayout.Height +
descriptLayout.Height) - 4);
Also, this is the part of the control that will change if the control is disabled. The text need only change color. The image, however, needs to be converted to grayscale if it hasn’t been done already. Events to OverrideThere are a few events that need to be overridden to get the CommandLink to behave like we want:
Conclusion and ImprovementsAt the end, we are left with a control that has the basic functionality of a button but the appearance of a Vista-style CommandLink. The implementation is meant to be compatible for older versions of Windows, so there are optional improvements that can be done. For example, there is no support for gradual fading like Vista controls do, and for now, the image has to be on the left side.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||