Create custom UI appearance for WinForms RadioButton - part 3
By ganton ~ July 9th, 2008. Filed under: WinForms.
(All posts in this series: Post 1, Post 2, Post 3, Post 4, Post 5, Post 6, Source Code)
It is my third post of WinForms controls with custom UI appearance. Here I’ll provide a custom radio button. For its implementation I’ll use CustomCheckBoxUIAppearance from my old post. As with CustomCheckBox (see my old post) it will be used for configuring UI appearance of the radio button. Both CustomCheckBox and CustomRadioButton controls are quite similar. Consequently, all have been said for CustomCheckBox control is valid for CustomRadioButton control. It is for sure that there are some differences :). The first one is that CustomRadioButton inherites from standard RadioButton (line 3) instead of CheckBox. The second difference is that here in OnPaint method we’ll use FillEllipse and DrawEllipse in order to paint radio button circle and its tick (line 79 -97). The third one is that we will use CustomCheckBoxUIAppearance’s TickThicness in some different way that it has been used in CustomCheckBox. When CustomRadioButton’s state is checked we’ll fill a small circle (our tick) into the external circle (line 86 - 89). Using TickThicness value we’ll correct tick’s yield to external circle border. This way we are able to provide diffferent look of our radio button.
Here’s the implementation of CustomRadioButton control.
public class CustomRadioButton : RadioButton
{
private CustomCheckBoxUIAppearance _customAppearance;
private bool _enableCustomUIAppearance;
[Description("If true control's is drawn using custom UI appearance, otherwise it appears using standard drawing."), Category("Custom Appearance"),
DefaultValue(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool EnableCustomUIAppearance
{
get { return _enableCustomUIAppearance; }
set
{
if (_enableCustomUIAppearance != value)
{
_enableCustomUIAppearance = value;
if (AutoSize)
{
AutoSize = false;
}
Invalidate();
}
}
}
[Description("This property specifies the way of drawing the control."), Category("Custom Appearance"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public CustomCheckBoxUIAppearance CustomAppearance
{
get { return _customAppearance; }
}
public CustomRadioButton()
{
_enableCustomUIAppearance = true;
_customAppearance = new CustomCheckBoxUIAppearance(this);
}
protected override void OnPaint(PaintEventArgs pevent)
{
// Call base class' OnPaint
base.OnPaint(pevent);
if (!_enableCustomUIAppearance)
{
return;
}
// padding of the standard RadioButton
int offset = 2;
// distance betwen RadioButton area and included label
int distance = 5;
int radioButtonWidthHeight = 12;
Graphics graphics = pevent.Graphics;
graphics.Clear(BackColor);
// get Text measure according to selected Font
SizeF stringMeasure = graphics.MeasureString(Text, Font);
// Set graphics object to paint nice using antialias.
if (_customAppearance.EnableAntiAlias)
{
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
}
// calculate offsets
int leftOffset = offset + Padding.Left;
int topOffset = (int)(ClientRectangle.Height - stringMeasure.Height) / 2;
if (topOffset < 0)
{
topOffset = offset + Padding.Top;
}
else
{
topOffset += Padding.Top;
}
if (Checked)
{
// Fill circle of the radio button
graphics.FillEllipse(new SolidBrush(_customAppearance.CheckedBackColor), leftOffset, topOffset, radioButtonWidthHeight, radioButtonWidthHeight);
// Draw circle of the radio button
graphics.DrawEllipse(new Pen(_customAppearance.CheckedBorderColor, _customAppearance.BorderThicness), leftOffset, topOffset, radioButtonWidthHeight, radioButtonWidthHeight);
// Fill circle of the radio button tick
int internalCircleWidthHeight = radioButtonWidthHeight - _customAppearance.BorderThicness * 2 - _customAppearance.TickThickness * 2;
int internalCircleOffset = _customAppearance.BorderThicness + _customAppearance.TickThickness;
graphics.FillEllipse(new SolidBrush(_customAppearance.TickColor), leftOffset + internalCircleOffset,
topOffset + internalCircleOffset, internalCircleWidthHeight, internalCircleWidthHeight);
}
else
{
// Fill circle of the radio button
graphics.FillEllipse(new SolidBrush(_customAppearance.BackColor), leftOffset, topOffset, radioButtonWidthHeight, radioButtonWidthHeight);
// Draw circle of the radio button
graphics.DrawEllipse(new Pen(_customAppearance.BorderColor, _customAppearance.BorderThicness), leftOffset, topOffset, radioButtonWidthHeight, radioButtonWidthHeight);
}
graphics.DrawString(Text, Font, new SolidBrush(ForeColor), leftOffset + radioButtonWidthHeight + distance, topOffset);
}
protected override void OnAutoSizeChanged(EventArgs e)
{
if (_enableCustomUIAppearance)
{
if (AutoSize)
{
AutoSize = false;
}
}
base.OnAutoSizeChanged(e);
}
}
Below is the output of CustomRadioButton in different configuration.

July 11th, 2008 at 4:46 pm
[...] Create custom UI appearance for WinForms RadioButton - part 3 [...]
July 31st, 2008 at 3:07 pm
[...] posts in this series: Post 1, Post 2, Post 3, Post 4, Post 5, Post 6, Source [...]
July 31st, 2008 at 3:10 pm
[...] posts in this series: Post 1, Post 2, Post 3, Post 4, Post 5, Post 6, Source [...]
August 6th, 2008 at 4:37 am
thank you