none
How to make a toolstrip button look like a 3D button

    Question

  • I would like my ToolStrip button to actually look like a button instead of this flat thing that is the default. I would also like for it to depress when the user clicks on it, just like a standard Windows form button. I've spend a couple of hours searching on this and can't find a solution. Suggestions are appreciated.
    Monday, April 30, 2012 2:09 PM

Answers

  • I don't know whether this will help you or not.  I like to maximize the useful area on my forms so I use a borderless, movable, resizable form with a custom menu for my base form:

    I use ControlPaint to draw the buttons.  Here's the code:

    Public Class BaseForm
      
    Inherits Form
      
    Friend MS As New Menu(Me)
      
    Protected Overrides Sub OnShown(e As System.EventArgs)
        
    MyBase.OnShown(e)
        
    Me.ClientSize = MS.Size
      
    End Sub
      
    Protected Overrides ReadOnly Property CreateParams() As CreateParams
        
    Get
          
    Dim CP As CreateParams = MyBase.CreateParams
          CP.Style = &HE0000
          
    Return CP
        
    End Get
      
    End Property
    End Class

    Public Class Menu
      
    Inherits Panel
      
    Friend HeaderTexts() As String = {"Base Form""Button1""Button2""Button3""X"}
      
    Friend HeaderWidths() As Integer = {100, 100, 100, 100, 20}
      
    Friend Btns() As Btn
      
    Friend BtnDownIndex As Integer = -1
      
    Sub New(ByVal Parent As Form)
        
    ReDim Btns(HeaderTexts.Length - 1)
        
    Dim L As Integer = 1
        
    For I As Integer = 0 To HeaderTexts.Length - 1
          
    Dim R As New Rectangle(L, 0, HeaderWidths(I), 20)
          Btns(I) = 
    New Btn(R, HeaderTexts(I), Font)
          L += HeaderWidths(I)
        
    Next
        Btns(0).Color = 
    Color.Blue
        Btns(Btns.Length - 1).Cap = 
    CaptionButton.Close
        
    Me.ClientSize = New Size(L, Btns(0).Bounds.Height)
        
    Me.Parent = Parent
      
    End Sub
      
    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        
    MyBase.OnPaint(e)
        
    For I As Integer = 0 To Btns.Length - 1
          
    If Btns(I).Bounds.IntersectsWith(e.ClipRectangle) Then
            Btns(I).DrawBtn(e.Graphics, 
    If(BtnDownIndex = I, ButtonState.Pushed, ButtonState.Normal))
          
    End If
        
    Next
      
    End Sub
      
    Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
        
    For I As Integer = 0 To Btns.Length - 1
          
    If Btns(I).Bounds.Contains(e.Location) Then
            BtnDownIndex = I
            
    Select Case I
              
    Case 0
                
    Me.Capture = False
                
    Me.WndProc(Message.Create(Parent.Handle, &HA1, New IntPtr(2), IntPtr.Zero))
                
    Return
              
    Case Btns.Length - 1
                
    DirectCast(Me.Parent, Form).Close()
            
    End Select
            
    Me.Invalidate(Btns(I).Bounds)
          
    End If
        
    Next
        
    MyBase.OnMouseDown(e)
      
    End Sub
      
    Protected Overrides Sub OnMouseUp(e As System.Windows.Forms.MouseEventArgs)
        
    MyBase.OnMouseUp(e)
        Invalidate(Btns(BtnDownIndex).Bounds)
        BtnDownIndex = -1
      
    End Sub
    End Class

    Public Class Btn
      
    Friend Bounds As Rectangle
      
    Friend Text As String
      
    Friend Font As Font
      
    Friend SF As New StringFormat(StringFormat.GenericTypographic)
      
    Friend Cap As CaptionButton = CType(-1, CaptionButton)
      
    Friend Color As Color = Nothing
      
    Sub New(Bounds As Rectangle, Text As String, Font As Font)
        
    Me.Bounds = Bounds
        
    Me.Text = Text
        
    Me.Font = Font
        
    Me.SF.Alignment = StringAlignment.Center
        
    Me.SF.LineAlignment = StringAlignment.Center
      
    End Sub
      
    Sub DrawBtn(G As GraphicsOptional State As ButtonState = ButtonState.Normal)
        
    If Cap < 0 Then
          
    If Color = Nothing Then
            
    ControlPaint.DrawButton(G, Me.Bounds, State)
            G.DrawString(Text, Font, 
    Brushes.Black, Bounds, SF)
          
    Else
            G.FillRectangle(
    New SolidBrush(Color), Me.Bounds)
            G.DrawString(
    Me.Text, Me.Font, Brushes.White, Me.Bounds, Me.SF)
          
    End If
        
    Else
          
    ControlPaint.DrawCaptionButton(G, Me.Bounds, Cap, State)
        
    End If
      
    End Sub
    End Class







    • Proposed as answer by btickle1 Wednesday, May 02, 2012 7:38 AM
    • Marked as answer by Mike FengModerator Tuesday, May 08, 2012 1:16 PM
    Monday, April 30, 2012 6:46 PM

All replies

  • I don't know whether this will help you or not.  I like to maximize the useful area on my forms so I use a borderless, movable, resizable form with a custom menu for my base form:

    I use ControlPaint to draw the buttons.  Here's the code:

    Public Class BaseForm
      
    Inherits Form
      
    Friend MS As New Menu(Me)
      
    Protected Overrides Sub OnShown(e As System.EventArgs)
        
    MyBase.OnShown(e)
        
    Me.ClientSize = MS.Size
      
    End Sub
      
    Protected Overrides ReadOnly Property CreateParams() As CreateParams
        
    Get
          
    Dim CP As CreateParams = MyBase.CreateParams
          CP.Style = &HE0000
          
    Return CP
        
    End Get
      
    End Property
    End Class

    Public Class Menu
      
    Inherits Panel
      
    Friend HeaderTexts() As String = {"Base Form""Button1""Button2""Button3""X"}
      
    Friend HeaderWidths() As Integer = {100, 100, 100, 100, 20}
      
    Friend Btns() As Btn
      
    Friend BtnDownIndex As Integer = -1
      
    Sub New(ByVal Parent As Form)
        
    ReDim Btns(HeaderTexts.Length - 1)
        
    Dim L As Integer = 1
        
    For I As Integer = 0 To HeaderTexts.Length - 1
          
    Dim R As New Rectangle(L, 0, HeaderWidths(I), 20)
          Btns(I) = 
    New Btn(R, HeaderTexts(I), Font)
          L += HeaderWidths(I)
        
    Next
        Btns(0).Color = 
    Color.Blue
        Btns(Btns.Length - 1).Cap = 
    CaptionButton.Close
        
    Me.ClientSize = New Size(L, Btns(0).Bounds.Height)
        
    Me.Parent = Parent
      
    End Sub
      
    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        
    MyBase.OnPaint(e)
        
    For I As Integer = 0 To Btns.Length - 1
          
    If Btns(I).Bounds.IntersectsWith(e.ClipRectangle) Then
            Btns(I).DrawBtn(e.Graphics, 
    If(BtnDownIndex = I, ButtonState.Pushed, ButtonState.Normal))
          
    End If
        
    Next
      
    End Sub
      
    Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
        
    For I As Integer = 0 To Btns.Length - 1
          
    If Btns(I).Bounds.Contains(e.Location) Then
            BtnDownIndex = I
            
    Select Case I
              
    Case 0
                
    Me.Capture = False
                
    Me.WndProc(Message.Create(Parent.Handle, &HA1, New IntPtr(2), IntPtr.Zero))
                
    Return
              
    Case Btns.Length - 1
                
    DirectCast(Me.Parent, Form).Close()
            
    End Select
            
    Me.Invalidate(Btns(I).Bounds)
          
    End If
        
    Next
        
    MyBase.OnMouseDown(e)
      
    End Sub
      
    Protected Overrides Sub OnMouseUp(e As System.Windows.Forms.MouseEventArgs)
        
    MyBase.OnMouseUp(e)
        Invalidate(Btns(BtnDownIndex).Bounds)
        BtnDownIndex = -1
      
    End Sub
    End Class

    Public Class Btn
      
    Friend Bounds As Rectangle
      
    Friend Text As String
      
    Friend Font As Font
      
    Friend SF As New StringFormat(StringFormat.GenericTypographic)
      
    Friend Cap As CaptionButton = CType(-1, CaptionButton)
      
    Friend Color As Color = Nothing
      
    Sub New(Bounds As Rectangle, Text As String, Font As Font)
        
    Me.Bounds = Bounds
        
    Me.Text = Text
        
    Me.Font = Font
        
    Me.SF.Alignment = StringAlignment.Center
        
    Me.SF.LineAlignment = StringAlignment.Center
      
    End Sub
      
    Sub DrawBtn(G As GraphicsOptional State As ButtonState = ButtonState.Normal)
        
    If Cap < 0 Then
          
    If Color = Nothing Then
            
    ControlPaint.DrawButton(G, Me.Bounds, State)
            G.DrawString(Text, Font, 
    Brushes.Black, Bounds, SF)
          
    Else
            G.FillRectangle(
    New SolidBrush(Color), Me.Bounds)
            G.DrawString(
    Me.Text, Me.Font, Brushes.White, Me.Bounds, Me.SF)
          
    End If
        
    Else
          
    ControlPaint.DrawCaptionButton(G, Me.Bounds, Cap, State)
        
    End If
      
    End Sub
    End Class







    • Proposed as answer by btickle1 Wednesday, May 02, 2012 7:38 AM
    • Marked as answer by Mike FengModerator Tuesday, May 08, 2012 1:16 PM
    Monday, April 30, 2012 6:46 PM
  • Thank you John. Your screen shot looks like what I'm going after although I only have one button in my toolstrip. I will see if I can decipher your code to make this happen.
    Wednesday, May 02, 2012 2:15 AM
  • Hi Peak,

    Any update?

    Based on my understanding, John's reply should be helpful, so I marked it as answer, if you think it provides no help, please feel free to unmark it and keep following up.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, May 08, 2012 1:18 PM
  • You could use the ToolStripControlHost class to create a standard WinForm Button that you can add to your toolstrip.

    Add a new class to your project and place this code in it.  Build your application.  You should then be able to select this new toolstrip control from the dropdown menu in the designer.

    <System.ComponentModel.DesignTimeVisibleAttribute(True)> _
    <System.ComponentModel.DesignerCategory("code"), _
       System.Windows.Forms.Design.ToolStripItemDesignerAvailability( _
       System.Windows.Forms.Design.ToolStripItemDesignerAvailability.ToolStrip _
       Or System.Windows.Forms.Design.ToolStripItemDesignerAvailability.StatusStrip)> _
    Public Class ToolStripWinFormButton
       Inherits ToolStripControlHost
    
       Public Sub New()
          MyBase.New(New System.Windows.Forms.Button())
          HostedButton.FlatStyle = FlatStyle.Standard
       End Sub
    
       Public ReadOnly Property HostedButton() As System.Windows.Forms.Button
          Get
             Return CType(Me.Control, System.Windows.Forms.Button)
          End Get
       End Property
    
    End Class

    Tuesday, May 08, 2012 6:10 PM