Horizontal Lines

Just saw this post in a newsgroup about how to show the horizontal lines that Microsoft likes to use in their dialogs. A lot of people replied with ideas of using other controls, like panels, to achieve the desired effect – to me, a much simpler and more effective idea is to just create a control myself. So, the specific style described by the OP seems to be this:

This is what you get by using a label set to a height of 2 and with a BorderStyle of Fixed3D. The OP said explicitely that this was what he wanted, which I find curious because the lines in my Word Options dialog, for instance, look quite different:

So, to account for both needs, I included the etched border as well as the single line border in my sample. I’m sure there are millions of other line styles out there, but these should be simple to include once the framework is there. Here’s the control source code:

public enum HLineType {
  Etched,
  Single
}

public class HorizontalLine : Control {
  public HorizontalLine( ) {
    SetStyle(
      ControlStyles.AllPaintingInWmPaint |
      ControlStyles.FixedHeight |
      ControlStyles.OptimizedDoubleBuffer |
      ControlStyles.ResizeRedraw |
      ControlStyles.SupportsTransparentBackColor |
      ControlStyles.UserPaint, true);
    lineType = HLineType.Etched;
  }

  public override System.Drawing.Size GetPreferredSize(Size proposedSize) {
    if (proposedSize == Size.Empty)
      return new Size(150, 10);
    return proposedSize;
  }

  private HLineType lineType;
  [DefaultValue(HLineType.Etched)]
  public HLineType LineType {
    get {
      return lineType;
    }
    set {
      if (lineType != value) {
        lineType = value;
          CreatePen( );
          Invalidate( );
      }
    }
  }

  public override Color ForeColor {
    get {
      return base.ForeColor;
    }
    set {
      base.ForeColor = value;
      CreatePen();
    }
  }

  Pen pen;
  void CreatePen( ) {
    if (pen != null) {
      pen.Dispose( );
      pen = null;
    }

    if (lineType == HLineType.Single)
      pen = new Pen(ForeColor);
  }

  protected override void OnPaint(PaintEventArgs e) {
    base.OnPaint(e);
    switch (lineType) {
      case HLineType.Etched:
        ControlPaint.DrawBorder3D(e.Graphics, ClientRectangle,
          Border3DStyle.Etched, Border3DSide.Top);
        break;
      case HLineType.Single:
        e.Graphics.DrawLine(pen, 0, 0, Width - 1, 0);
        break;
    }
  }
}

This was done in VS 2005 beta 2. You might have to make minor changes for .NET 1 if needed - I’m not 100% sure about the flags in the SetStyle call, look them up if you need to.

Sorry, this blog does not support comments.

I used various blog hosting services since this blog was established in 2005, but unfortunately they turned out to be unreliable in the long term and comment threads were lost in unavoidable transitions. At this time I don't want to enable third-party services for comments since it has become obvious in recent years that these providers invariably monetize information about their visitors and users.

Please use the links in the page footer to get in touch with me. I'm available for conversations on Keybase, Matrix, Mastodon or Twitter, as well as via email.