Results 1 to 8 of 8

Thread: Separator control, including designer

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Separator control, including designer

    Here's a simple Separator control, that basically draws a 2 pixel '3d line' separator:


    It includes three properties:
    • Color1
    • Color2
    • Orientation

    Color1 is the Top or Left color, and Color2 is the Bottom or Right color, depending on the Orientation (either Vertical or Horizontal).


    I know what you're thinking, how hard is it to draw two lines? Well, this UserControl makes it very easy to do so during Design-time, especially since I wrote a small Designer class for it. This designer does two things:
    • Allows resizing in only one direction,
    • Adds Action List menu.

    If the Orientation property is set to Horizontal, the designer allows you to only resize it horizontally. In fact, the code in the UserControl already stops you from resizing it vertically, but the designer actually stops showing the vertical resizing cursor. This is very handy, because otherwise, you would have a hard time selecting the very thin line, since you would be either resizing it upward, or downward...

    The Action List menu is a small menu appearing when you click the [>] button in the designer, and hosts the properties I described for easy access. It also hosts a "Swap colors" method, which simply swaps out the two colors.


    Finally, the designer allows me to filter out a few properties that are nonsensical for this control.



    Full code here. To add it to your project:
    - Add a new UserControl and copy/paste this code.
    - Add a reference to System.Design by rightclicking the project name in the Solution Explorer and choosing Add Reference. Without this, the designer does not work and you will get errors.

    Code:
    Imports System.ComponentModel.Design
    Imports System.ComponentModel
    Imports System.Windows.Forms.Design
    
    <Designer(GetType(SeparatorDesigner))> _
    Public Class Separator
    
        Public Enum enmOrientation
            Horizontal
            Vertical
        End Enum
    
        Public Sub New()
            InitializeComponent()
            Me.Height = 2
        End Sub
    
        Private _Color1 As Color = SystemColors.ControlDark
        <DefaultValue(GetType(Color), "ControlDark")> _
        Public Property Color1() As Color
            Get
                Return _Color1
            End Get
            Set(ByVal value As Color)
                _Color1 = value
            End Set
        End Property
    
        Private _Color2 As Color = Color.White
        <DefaultValue(GetType(Color), "White")> _
        Public Property Color2() As Color
            Get
                Return _Color2
            End Get
            Set(ByVal value As Color)
                _Color2 = value
            End Set
        End Property
    
        Private _Orientation As enmOrientation = enmOrientation.Horizontal
        <DefaultValue(enmOrientation.Horizontal)> _
        Public Property Orientation() As enmOrientation
            Get
                Return _Orientation
            End Get
            Set(ByVal value As enmOrientation)
                _Orientation = value
    
                'Swap width and height
                If value = enmOrientation.Horizontal Then
                    Me.Width = Me.Height
                    Me.Height = 2
                Else
                    Me.Height = Me.Width
                    Me.Width = 2
                End If
            End Set
        End Property
    
        Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
            MyBase.OnResize(e)
            If Me.Orientation = enmOrientation.Horizontal Then
                Me.Height = 2
            Else
                Me.Width = 2
            End If
        End Sub
    
        Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
            MyBase.OnPaintBackground(e)
    
            If Me.Orientation = enmOrientation.Horizontal Then
                e.Graphics.DrawLine(New Pen(Me.Color1), 0, 0, Me.Width, 0)
                e.Graphics.DrawLine(New Pen(Me.Color2), 0, 1, Me.Width, 1)
            Else
                e.Graphics.DrawLine(New Pen(Me.Color1), 0, 0, 0, Me.Height)
                e.Graphics.DrawLine(New Pen(Me.Color2), 1, 0, 1, Me.Height)
            End If
        End Sub
    
    End Class
    
    Public Class SeparatorDesigner
        Inherits System.Windows.Forms.Design.ControlDesigner
    
        Private lists As DesignerActionListCollection
    
        'Retrieves the Separator control to which this designer belongs
        Private ReadOnly Property HostControl() As Separator
            Get
                Return DirectCast(Me.Control, Separator)
            End Get
        End Property
    
        'Adds the Action Lists (> menu) 
        Public Overrides ReadOnly Property ActionLists() As DesignerActionListCollection
            Get
                If lists Is Nothing Then
                    lists = New DesignerActionListCollection()
                    lists.Add(New SeparatorActionList(Me.Component))
                End If
                Return lists
            End Get
        End Property
    
        'Allows only horizontal/vertical resizing
        Public Overrides ReadOnly Property SelectionRules() As System.Windows.Forms.Design.SelectionRules
            Get
                Dim selRules As SelectionRules = Windows.Forms.Design.SelectionRules.Moveable
    
                If Me.HostControl.Orientation = Separator.enmOrientation.Horizontal Then
                    selRules = selRules Or Windows.Forms.Design.SelectionRules.LeftSizeable Or _
                                           Windows.Forms.Design.SelectionRules.RightSizeable
                Else
                    selRules = selRules Or Windows.Forms.Design.SelectionRules.TopSizeable Or _
                                           Windows.Forms.Design.SelectionRules.BottomSizeable
                End If
    
                Return selRules
            End Get
        End Property
    
        Protected Overrides Sub PostFilterProperties(ByVal properties As System.Collections.IDictionary)
            properties.Remove("BackColor")
            properties.Remove("BackgroundImage")
            properties.Remove("BackgroundImageLayout")
            properties.Remove("BorderStyle")
            properties.Remove("Font")
            properties.Remove("ForeColor")
            properties.Remove("RightToLeft")
            MyBase.PostFilterProperties(properties)
        End Sub
    
        'The class that shows the Action List (> menu) properties
        Public Class SeparatorActionList
            Inherits DesignerActionList
    
            Private _sep As Separator
            Private designerActionSvc As DesignerActionUIService = Nothing
    
            Public Sub New(ByVal component As IComponent)
                MyBase.New(component)
                _sep = DirectCast(component, Separator)
    
                Me.designerActionSvc = CType(GetService(GetType(DesignerActionUIService)), DesignerActionUIService)
            End Sub
    
            Public Property Color1() As Color
                Get
                    Return _sep.Color1
                End Get
                Set(ByVal value As Color)
                    _sep.Color1 = value
                End Set
            End Property
    
            Public Property Color2() As Color
                Get
                    Return _sep.Color2
                End Get
                Set(ByVal value As Color)
                    _sep.Color2 = value
                End Set
            End Property
    
            Public Property Orientation() As Separator.enmOrientation
                Get
                    Return _sep.Orientation
                End Get
                Set(ByVal value As Separator.enmOrientation)
                    _sep.Orientation = value
                End Set
            End Property
    
            Public Sub SwapColors()
                Dim c As Color = _sep.Color1
                _sep.Color1 = _sep.Color2
                _sep.Color2 = c
                designerActionSvc.Refresh(_sep)
            End Sub
    
            Public Overrides Function GetSortedActionItems() As System.ComponentModel.Design.DesignerActionItemCollection
                Dim items As New DesignerActionItemCollection
    
                items.Add(New DesignerActionHeaderItem("Properties"))
                items.Add(New DesignerActionPropertyItem("Color1", "Color1:", "Properties", "The top/left color."))
                items.Add(New DesignerActionPropertyItem("Color2", "Color2:", "Properties", "The bottom/right color."))
                items.Add(New DesignerActionPropertyItem("Orientation", "Orientation:", "Properties", "The orientation of the separator."))
                items.Add(New DesignerActionMethodItem(Me, "SwapColors", "Swap colors", "Properties", "Swaps the two colors.", True))
    
                Return (items)
            End Function
        End Class
    
    End Class

    Enjoy!

  2. #2
    Registered User
    Join Date
    Jul 2009
    Posts
    71

    Re: Separator control, including designer

    Looks great as it is used in Office 2003 applications as well. I will definately try it!
    btw, quite some code for a simple 2 pixels line
    Last edited by pimvdb; Aug 30th, 2009 at 07:24 AM.

  3. #3

  4. #4

  5. #5
    Lively Member Blupig's Avatar
    Join Date
    Apr 2008
    Posts
    118

    Re: Separator control, including designer

    Couldn't you just use the line control in the VB power packs?

  6. #6

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Separator control, including designer

    You could. But I think you would need two lines (the separator consists of two colors), which you would have to position very carefully alongside each other. Selecting and moving them would be a pain.

    This control just provides you with an easier alternative. It's also a very good example for designer classes and it's so simple.

  7. #7
    Master Of Orion ForumAccount's Avatar
    Join Date
    Jan 2009
    Location
    Canada
    Posts
    2,802

    Re: Separator control, including designer

    Quote Originally Posted by NickThissen View Post
    You could. But I think you would need two lines (the separator consists of two colors), which you would have to position very carefully alongside each other. Selecting and moving them would be a pain.

    This control just provides you with an easier alternative. It's also a very good example for designer classes and it's so simple.
    Not to mention using controls from the power packs requires the PowerPacks from Microsoft to be installed/registered in the GAC. For both the user and the designer. So Nick's is a +1 in that regard.

  8. #8
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Separator control, including designer

    There's another way of doing this for anyone that doesnt want to use Nick's method - Nick's code is probably more flexible and easier to work with but I just thought I would mention this method as its something I have used a lot when I needed that separator look:

    1. Add a groupbox to your form.
    2. Make the Text property blank (no text)
    3. Change the size property to *,8 . What I mean by that is - whatever number you want for the width but make sure the height is 8. So 100, 8 for a 100 pixel wide separator
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width