UnderlinedLabel I was tired of always looking for a way to underline labels like in Windows property dialogs. I created this little control that allows you to set a two-tone line above, below behind or in front of a label (even through it!) to solve that problem.

The image to the left shows the control with the label text "Connection Preferences" using it's default settings.

To use the control in your project, create a new class file, erase everything in the class file, and paste the code snippet here into that new code file. You can change the namespace if you like and you can omit the copyright comment at the top (it's okay, it's open source to the extreme, I don't care if you take credit for it, it wasn't all that complicated to do).

Some of the features:

Offseting the "Line" by setting the left and right offset properties will shorten the line by x number of pixels starting on either the left or right or both.
Offsetting each line tone by setting Line1 or Line2 offset will move the first or second line up into the label text or above the label text.
Each line can have its own thickness setting as well and it's own color setting.
By default the lines are setup to simulate the 3D horizontal line that you might see online or in an application.

Other possible uses could be a label with no text that you auto-size to just draw a line (horizontal only of course) on the designer surface.

Because the control inherits from the label control, all label properties and events are available, no other events were added, but you could if you have some creative ideas.

Some use tips:

  • The control by default is set to autosize, if you want the label to stretch past the end of the text (like in the example), switch the autosize property to false and just set the control size to whatever you want and the lines will grow to fit. You might also want to set anchors on the left and right if your form resizes and you want the line to resize when the form does.
  • If you want the line to be on the right of the text or the left, you might need to play with the padding, or even better, set the left offset programatically (if you intend to have the text change), otherwise just setting the offsets will achieve this effect.

Feedback/Suggestions are welcome!

If someone would prefer to use a compiled dll file, let me know and I can upload one, but otherwise enjoy!

More images:
UnderlinedLabelRight The control with the line to the right of the label text, achieved by setting LeftOffset = 95, Line1Offset =7, Line2Offset = 6.
UnderlinedLabelLeft The control with the line to the left of the label text, achieved by setting the text alignment to top right, RightOffset = 100, Line1Offset = 7, Line2Offset = 6.

Remember though, the offsets will be different depending on your text length and the height and length of your label, that's why it might be a good idea to set them programmatically.

// ----------------------------------------------------------------------------------
// Public Code File: Common Control: UnderlinedLabel
// 
// Copyright (c) Zachary Aaron Weber. All rights reserved.
// 
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
// This code file may be protected by a non-disclosure agreement and may subject you
// to disiplinary action or legal ramifications if copied from the code file/project
// archive repository on the PDC servers with the intention of disclosing the file,
// in whole, or in part, without the consent of PDC.
// ----------------------------------------------------------------------------------
// FID: P_CCU|001
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

// 
// Change the namespace if you like
// 
namespace PhoenixDevelopment.Controls.Common
{
    public partial class UnderlinedLabel : Label
    {
        #region Properties

        private int _LeftOffset = 3;

        private int _RightOffset = 3;

        private int _Line1Offset = 1;

        private int _Line2Offset = 0;

        private int _Line1Thickness = 1;

        private int _Line2Thickness = 1;

        private Color _Line1Color = Color.LightGray;

        private Color _Line2Color = Color.White;

        /// <summary>
        /// Gets or Sets the left offset, in pixels, of the lines.
        /// </summary>
        [Description("Gets or Sets the left offset, in pixels, of the lines."), Browsable(true), Category("Underlined Label")]
        public int LeftOffset
        {
            get { return _LeftOffset; }
            set {
                if (value < 0)
                {
                    throw new ArgumentOutOfRangeException("LeftOffset", value, "The LeftOffset value cannot be negative.");
                }
                _LeftOffset = value; }
        }

        /// <summary>
        /// Gets or Sets the right offset, in pixels, of the lines.
        /// </summary>
        [Description("Gets or Sets the right offset, in pixels, of the lines."), Browsable(true), Category("Underlined Label")]
        public int RightOffset
        {
            get { return _RightOffset; }
            set {
                if (value < 0)
                {
                    throw new ArgumentOutOfRangeException("RightOffset", value, "The RightOffset value cannot be negative.");
                }
                _RightOffset = value; }
        }

        /// <summary>
        /// Gets or Sets the horizontal offset, in pixels, of Line1 in relation to the bottom of the control.
        /// </summary>
        [Description("Gets or Sets the horizontal offset, in pixels, of Line1 in relation to the bottom of the control."), Browsable(true), Category("Underlined Label")]
        public int Line1Offset
        {
            get { return _Line1Offset; }
            set {
                if (value < 0)
                {
                    throw new ArgumentOutOfRangeException("Line1Offset", value, "The Line1Offset value cannot be negative.");
                }
                _Line1Offset = value; }
        }

        /// <summary>
        /// Gets or Sets the horizontal offset, in pixels, of Line2 in relation to the bottom of the control.
        /// </summary>
        [Description("Gets or Sets the horizontal offset, in pixels, of Line2 in relation to the bottom of the control."), Browsable(true), Category("Underlined Label")]
        public int Line2Offset
        {
            get { return _Line2Offset; }
            set {
                if (value < 0)
                {
                    throw new ArgumentOutOfRangeException("Line2Offset", value, "The Line2Offset value cannot be negative.");
                }
                _Line2Offset = value; }
        }

        /// <summary>
        /// Gets or Sets the thickness, in pixels, of Line1.
        /// </summary>
        [Description("Gets or Sets the thickness, in pixels of Line1."), Browsable(true), Category("Underlined Label")]
        public int Line1Thickness
        {
            get { return _Line1Thickness; }
            set { _Line1Thickness = value; }
        }

        /// <summary>
        /// Gets or Sets the thickness, in pixels, of Line2.
        /// </summary>
        [Description("Gets or Sets the thickness, in pixels, of Line2."), Browsable(true), Category("Underlined Label")]
        public int Line2Thickness
        {
            get { return _Line2Thickness; }
            set { _Line2Thickness = value; }
        }

        /// <summary>
        /// Gets or Sets the <see cref="System.Drawing.Color"/> of Line1.
        /// </summary>
        [Description("Gets or Sets the System.Drawing.Color of Line1."), Browsable(true), Category("Underlined Label")]
        public Color Line1Color
        {
            get { return _Line1Color; }
            set { _Line1Color = value; }
        }

        /// <summary>
        /// Gets or Sets the <see cref="System.Drawing.Color"/> of Line2.
        /// </summary>
        [Description("Gets or Sets the System.Drawing.Color of Line2."), Browsable(true), Category("Underlined Label")]
        public Color Line2Color
        {
            get { return _Line2Color; }
            set { _Line2Color = value; }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Creates an instance of a UnderlinedLabel control.
        /// </summary>
        public UnderlinedLabel()
        {
            InitializeComponent();
        }

        #endregion

        #region Overrides

        /// <summary>
        /// Draws the lines.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            Point Line1Start = new Point(0 + LeftOffset, Height - Line1Offset);
            Point Line1End = new Point(Width - RightOffset, Height - Line1Offset);
            Pen Line1Pen = new Pen(Line1Color, Line1Thickness);

            Point Line2Start = new Point(0 + LeftOffset, Height - Line2Offset);
            Point Line2End = new Point(Width - RightOffset, Height - Line2Offset);
            Pen Line2Pen = new Pen(Line2Color, Line2Thickness);

            e.Graphics.DrawLine(Line1Pen, Line1Start, Line1End);
            e.Graphics.DrawLine(Line2Pen, Line2Start, Line2End);
            base.OnPaint(e);
        }

        #endregion
		
		        /// <summary> 
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary> 
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary> 
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // UnderlinedLabel
            // 
            this.BackColor = System.Drawing.Color.Transparent;
            this.Padding = new System.Windows.Forms.Padding(0, 0, 0, 2);
            this.ResumeLayout(false);

        }

        #endregion
    }
}