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.

      4 Responses to Create custom UI appearance for WinForms RadioButton - part 3

      1. Create custom UI appearance for WinForms CheckBox - part 2 : Anton Gochev’s Weblog

        [...] Create custom UI appearance for WinForms RadioButton - part 3 [...]

      2. Create custom UI appearance for WinForms CustomButton - part 4 » Anton Gochev’s Weblog

        [...] posts in this series: Post 1, Post 2, Post 3, Post 4, Post 5, Post 6, Source [...]

      3. Create custom UI appearance for WinForms controls - part 1 » Anton Gochev’s Weblog

        [...] posts in this series: Post 1, Post 2, Post 3, Post 4, Post 5, Post 6, Source [...]

      4. whydzxx

        thank you

      Leave a Reply