
Adding a standard border to a controlThe Control class doesn't have a border style property so creating controls with standard borders can present a problem. Many people assume the border is drawn in the OnPaint override but this creates a problem because it uses up some of the client rectangle which always has to be compensated for when doing the "real" drawing in a control. Really, the control border should be a non-client item and drawn for us by the system. The secret to enabling this feature is in the window creation parameters which are used every time a control is created or recreated. The CreateParams property may be overridden to return a set of creation parameters that include the flags which add borders to the control. There also needs to be a mechanism for specifying which border is to be displayed so a property of type BorderStyle is ideal. The basic control shown in the following C# and VB listings show how to do this. VB Imports System Imports System.ComponentModel Imports System.Windows.Forms
Namespace controlborders
Public Class ControlEx Inherits Control
Private _borderStyle As BorderStyle
< _ Category("Appearance"), _ Description("The border style") _ > _ Public Property BorderStyle() As BorderStyle Get Return _borderStyle End Get Set(ByVal Value As BorderStyle) _borderStyle = Value Me.RecreateHandle() Invalidate() End Set End Property
Protected Overrides ReadOnly Property CreateParams() As CreateParams Get Const WS_BORDER As Integer = &H800000 Const WS_EX_STATICEDGE As Integer = &H20000 Dim cp As CreateParams = MyBase.CreateParams Select Case _borderStyle Case BorderStyle.FixedSingle cp.Style = cp.Style Or WS_BORDER Case BorderStyle.Fixed3D cp.ExStyle = cp.ExStyle Or WS_EX_STATICEDGE End Select Return cp End Get End Property
Public Sub New() End Sub 'New End Class 'ControlEx End Namespace 'controlborders
C# namespace controlborders { using System; using System.Windows.Forms;
public class ControlEx : Control {
private BorderStyle _borderStyle;
[ Category("Appearance"), Description("The border style") ] public BorderStyle BorderStyle { get { return _borderStyle; } set { _borderStyle = value; this.RecreateHandle(); Invalidate(); } }
protected override CreateParams CreateParams { get { const int WS_BORDER=0x00800000; const int WS_EX_STATICEDGE=0x00020000; CreateParams cp=base.CreateParams; switch (_borderStyle) { case BorderStyle.FixedSingle: cp.Style|=WS_BORDER; break; case BorderStyle.Fixed3D: cp.ExStyle |= WS_EX_STATICEDGE; break; } return cp; } }
public ControlEx() { } } }
Any class which derives from ControlEx will now have a BorderStyle property that can be used to select the FixedSingle or Fixed3D styles. Return to the Tips and Tricks index Copyright Robert W. Powell 2004. All rights reserved. |