Click here to Skip to main content
Click here to Skip to main content

Custom Button Control with Gradient Colors and Extra Image (VB.NET)

By , 11 Jan 2013
 

Introduction

The CButton is a simple custom button control written in VB.NET. Sorry I didn't realize the "C" prefix was a language specific thing when I started. It is just short for Custom Button. I won't let it happen again. This is a great alternative to the plain Microsoft button.

Here is a list of the primary features:

  1. Change the Shape of the button
  2. Adjust the corners of a round rectangle
  3. Solid and Multi color Fills
  4. Text shadow and margin
  5. Adjustable rollover and click color change with simulated click movement
  6. Normal button image and/or additional sideimage

I improved design time editing in Version 1.2 by adding UITypeEditors and ControlDesigners. See UITypeEditorsDemo[^] for a detailed explanation. This enabled me to combine some properties into one single property, or improve on others.

For example:

  • ButtonColorA, ButtonColorB, and ButtonColorC were combined into ColorFillBlend allowing unlimited Color blend instead of being limited to only three colors
  • ButtonColorCenterPoint, and ButtonColorCenterPtOffset were combined into FocalPoints
  • CornerRadius became an expandable property Corners allowing each corner to be adjusted separately

Background

Here is another example of needing (well, let's be honest, a plain button would work, so I wanted) a better looking and visually versatile button. There are a lot of great button controls already, but not with all the features I was looking for. Basically, I created the properties I was looking for, and then took over the OnPaint to draw it the way I wanted.

Control Properties

Here is a list of the primary properties:

  • Shape

    What shape the button is (Rectangle, Ellipse, Triangle)

  • ColorFillBlend

    Colors to use in gradient blend fills

  • BorderColor, BorderShow

    Show the border in a different color

  • FillType

    What color gradient type to use (Solid, Linear, or Path)

  • FocalPoints

    CenterPoint and FocusScales for Path Gradient Type Fills

  • Corners

    Radius for each corner arc

  • DimFactorHover, DimFactorClick

    Number to adjust the buttons color during mouse rollover and click

  • TextShadow, TextShadowShow

    Show or not show the shadow of the text and in what color

  • TextMargin

    Push the text away from the inside edge of the button

  • TextSmoothingMode

    Set the TextRenderingHint of the Graphics Object for better looking text

  • SideImage

    Add an extra image that can be placed outside the button surface

  • Padding

    Offset the edges of the ButtonArea from the edge of the Control

Using the Code

Once you get the CButton designed the way you want, there isn't really any complicated code. Just use it like a normal button.

Because the Click event fires if you click anywhere on the control, I added two new Events; the ClickButtonArea event in Version 1.1 to fire only when the mouse clicks inside the button part of the control, and the SideImageClicked event in Version 2.0.

    'Add a new Click event for only when the ButtonArea or SideImage is Clicked
    Public Event ClickButtonArea(ByVal Sender As Object, _
        ByVal e As System.Windows.Forms.MouseEventArgs)
    Public Event SideImageClicked(ByVal Sender As Object, _
        ByVal e As System.Windows.Forms.MouseEventArgs)


Private Sub CButton_MouseUp(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
    If MouseDrawState = eMouseDrawState.Down _
        Then RaiseEvent ClickButtonArea(Me, New EventArgs)
    MouseDrawState = eMouseDrawState.Up
    Me.Invalidate(ButtonArea)
End Sub

Points of Interest

The control is just a process of layering the parts together in the right positions. There are four main areas to track. The control area, button area, text area, and image area. The button area is reduced from the control area by the control padding values. The text area is reduced from the button area by the text margin values and the image area. The image area is based on the image size. The items are placed into these areas based on their layout options.

Protected Overrides Sub _
    OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
    e.Graphics.TextRenderingHint = _TextSmoothingMode

    'Gray the Text and Border Colors if Disabled
    Dim bColor, tColor, tsColor As Color
    If Me.Enabled Then
        bColor = _BorderColor
        tColor = Me.ForeColor
        tsColor = _TextShadow
    Else
        bColor = GrayTheColor(_BorderColor)
        tColor = GrayTheColor(Me.ForeColor)
        tsColor = GrayTheColor(_TextShadow)
    End If

    Dim MyPen As New Pen(bColor)
    MyPen.Alignment = PenAlignment.Inset

    'Shrink the Area so the Border draws correctly, _
    'then trim off the Padding to get the button surface area
    ButtonArea = AdjustRect(New RectangleF(0, 0, _
        Me.Size.Width - 1, Me.Size.Height - 1), Me.Padding)

    'Create the ButtonArea Path
    Dim gp As GraphicsPath = GetPath()

    If Me.BackgroundImage Is Nothing Then

        'Color the ButtonArea with the right Brush
        Select Case Me.FillType
            Case eFillType.Solid
                Using br As Brush = New SolidBrush(GetFill)
                    e.Graphics.FillPath(br, gp)
                End Using

            Case eFillType.GradientPath
                Using br As PathGradientBrush = New PathGradientBrush(gp)
                    Dim cb As New ColorBlend
                    cb.Colors = GetFillBlend()
                    cb.Positions = Me.ColorFillBlend.iPoint

                    br.FocusScales = FocalPoints.FocusScales
                    br.CenterPoint = New PointF( _
                        Me.Width * FocalPoints.CenterPoint.X, _
                        Me.Height * FocalPoints.CenterPoint.Y)
                    br.InterpolationColors = cb

                    e.Graphics.FillPath(br, gp)
                End Using

            Case eFillType.GradientLinear
                Using br As LinearGradientBrush = New LinearGradientBrush( _
                  ButtonArea, Color.White, Color.White, FillTypeLinear)
                    Dim cb As New ColorBlend
                    cb.Colors = GetFillBlend()
                    cb.Positions = Me.ColorFillBlend.iPoint

                    br.InterpolationColors = cb

                    e.Graphics.FillPath(br, gp)
                End Using

        End Select
    End If

    If BorderShow Then
        e.Graphics.DrawPath(MyPen, gp)
    End If
    gp.Dispose()

    Dim ipt As PointF = ImageLocation(GetStringFormat(Me.SideImageAlign), _
        Me.Size, Me.SideImageSize)

    rectSideImage = New Rectangle(CInt(ipt.X), CInt(ipt.Y), _
        Me.SideImageSize.Width, Me.SideImageSize.Height)

    'Put the SideImage behind the Text
    If SideImageBehindText AndAlso Me.SideImage IsNot Nothing Then
        If Me.Enabled Then
            e.Graphics.DrawImage(Me.SideImage, ipt.X, ipt.Y, _
                Me.SideImageSize.Width, Me.SideImageSize.Height)
        Else
            ControlPaint.DrawImageDisabled(e.Graphics, _
            New Bitmap(Me.SideImage, Me.SideImageSize.Width, _
            Me.SideImageSize.Height), _
            CInt(ipt.X), CInt(ipt.Y), Me.BackColor)
        End If
    End If

    'Layout the Text and Image on the button surface
    SetImageAndText(e.Graphics)

    If Not Me.Image Is Nothing Then
        If Me.Enabled Then
            e.Graphics.DrawImage(Me.Image, Imagept.X, Imagept.Y, _
                Me.ImageSize.Width, Me.ImageSize.Height)
        Else
            ControlPaint.DrawImageDisabled(e.Graphics, Me.Image, _
                CInt(Imagept.X), CInt(Imagept.Y), Me.BackColor)
        End If
    End If

    'Draw the Text and Shadow
    If TextShadowShow Then
        TextArea.Offset(1, 1)
        e.Graphics.DrawString(Me.Text, Me.Font, _
            New SolidBrush(tsColor), TextArea, GetStringFormat(Me.TextAlign))
        TextArea.Offset(-1, -1)
    End If
    e.Graphics.DrawString(Me.Text, Me.Font, _
        New SolidBrush(tColor), TextArea, GetStringFormat(Me.TextAlign))

    'Put the SideImage in front of the Text
    If Not SideImageBehindText AndAlso Not Me.SideImage Is Nothing Then
        If Me.Enabled Then
            e.Graphics.DrawImage(Me.SideImage, ipt.X, ipt.Y, _
                Me.SideImageSize.Width, Me.SideImageSize.Height)
        Else
            ControlPaint.DrawImageDisabled(e.Graphics, _
            New Bitmap(Me.SideImage, _
            Me.SideImageSize.Width, Me.SideImageSize.Height), _
            CInt(ipt.X), CInt(ipt.Y), Me.BackColor)
        End If
    End If

    MyPen.Dispose()
End Sub

To Gray the colors when the control is disabled, I used two methods:

To Gray a single color, I used this Function:

Function GrayTheColor(ByVal GrayColor As Color) As Color
   Dim gray As Integer = _
    CInt(GrayColor.R * 0.3 + GrayColor.G * 0.59 + GrayColor.B * 0.11)
   Return Color.FromArgb(GrayColor.A, gray, gray, gray)
End Function

To Gray an Image, I originally used this Function:

Private Function EnableDisableImage(ByVal img As Image) As Bitmap
    If Me.Enabled Then Return img
    Dim bm As Bitmap = New Bitmap(img.Width, img.Height)
    Dim g As Graphics = Graphics.FromImage(bm)
    Dim cm As ColorMatrix = New ColorMatrix(New Single()() _
         {New Single() {0.5, 0.5, 0.5, 0, 0}, _
        New Single() {0.5, 0.5, 0.5, 0, 0}, _
        New Single() {0.5, 0.5, 0.5, 0, 0}, _
        New Single() {0, 0, 0, 1, 0}, _
        New Single() {0, 0, 0, 0, 1}})

    Dim ia As ImageAttributes = New ImageAttributes()
    ia.SetColorMatrix(cm)
    g.DrawImage(img, New Rectangle(0, 0, img.Width, img.Height), 0, 0, _
        img.Width, img.Height, GraphicsUnit.Pixel, ia)
    g.Dispose()
    Return bm

End Function

In Version 2.0, I switched to the ControlPaint function because I thought the image was better looking.

ControlPaint.DrawImageDisabled(e.Graphics, Me.Image, _
    CInt(Imagept.X), CInt(Imagept.Y), Me.BackColor)

FocalPoints

New in Version 1.5, when the FillType is GradientPath a small square and circle selection will appear on the control. Drag the circle around to move the CenterPoint, and drag the square to move the FocusScales. Check out the UITypeEditorsDemo link above to see an explanation of this feature.

TypeConverter for ColorFillBlend

New in Version 2.0, a TypeConverter for the ColorFillBlend can convert a String representation of the blend to a cBlendItems to allow more precise tweaking and to easily copy a blend from one cButton to another.

History

  • Version 1.0 - May 2008
  • Version 1.1 - July 2008
    • Updated "Clickable Region" and added a ClickButtonArea event
  • Version 1.2 - September 2008
    • Updated Properties to use UITypeEditors and ControlDesigner
    • Added Triangular Buttons
  • Version 1.3 - September 2008
    • Button Area Click Fix. The button did not click when the mouse was moving
  • Version 1.4 - October 2008
    • Added Enable/Disable Feature
  • Version 1.5 - December 2008
    • Fixed the FocalPoints and Corners properties to immediately refresh the control when the child properties are changed in the PropertyGrid
    • Removed FocalPoints Modal UITypeEditor and added direct adjustment of the points on the design surface
  • Version 1.6 - January 2009
    • Added Mnemonic Keys based on NfErNo's suggestion.
  • Version 1.7 - April 2009
    • Added SendMessage for click through non button area
  • Version 1.8 - November 2009
    • Added Key events based on getholdofphil's suggestion
    • Fixed focus problem
  • Version 1.9 - July 2010
    • Switched the Disable Image routine to ControlPaint method
    • Added TextSmoothingMode property
    • Added SideImageClicked Event
    • Changed the ClickButtonArea EventArgs to MouseEventArgs to pass the mouse button easier
  • Version 2.0 - December 2011
    • Added IButtonControl Interface for PerformClick and DialogResult 
    • Added BlendItemsConverter to the cBlendItem Type 
  • Version 2.0 - January 2013
    • Added Visual Studio 2012 version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

SSDiver2112
Software Developer
United States United States
Member
I first got hooked on programing with the TI994A. After it finally lost all support I reluctantly moved to the Apple IIe. Thank You BeagleBros for getting me through. I wrote programs for my Scuba buisness during this time. Currently I am a Database manager and software developer. I started with VBA and VB6 and now having fun with VB.NET

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Questionerror CButtonLib.CButtonmemberquimicosa21 Apr '13 - 17:16 
Error   2   Value of type 'CButtonLib.CButton' cannot be converted to 'System.Windows.Forms.Control'.   C:\Documents and Settings\All Users\Documents\SkinSoft\VisualStyler\Projects\Visual Studio 2010\VB\Controls Sample\Form1.Designer.vb    108 25  VisualStylerControls

QuestionNewb with a problem after adding CbuttonsmemberMember 993531123 Mar '13 - 17:30 
First off, I want to say how awesome your control is. It's awesome!
 
I'm using Visual Studio 2012 and I created a very simple form with some regular buttons, some radio buttons, some hidden elements, etc... It's VERY rudimentary, but it worked. After seeing how ugly the regular buttons are, I found this site.
 
So here's the issue:
When I go and re-do all the old regular buttons with new Cbuttons, I have an odd event raised (it raises a click event on one of the radio buttons) when the form loads. It's odd because as long as I keep one of the old buttons on the form, I don't get the event, but if the Cbuttons are the only ones present, then the event triggers the radio button's procedure.
 
As the title states, I'm very new to vb.net. Is there any simple explanation as to how/why this might be happening? Any ideas on where to look for the cause?
GeneralCan popup design time editor be invoked at runtime?memberJonHB13 Mar '13 - 12:27 
I'm creating an interface where I modify button sizes, locations, colors, etc. at application runtime and restore those settings the next time the app is ran. I'd like to replace my buttons with CButton and be able to invoke the built-in property editor at runtime so I don't have to re-write that as part of my app. The editor I'm referring to is the one titled "CButtons Tasks" that you show in the screenshot. Is this possible?
GeneralRe: Can popup design time editor be invoked at runtime?memberSSDiver211218 Mar '13 - 15:56 
I do not believe the Smart Tag can be used at run time. You can use the PropertyGrid to edit the properties, but if you want something like the SmartTag you will have to build it.
 
SSDiver2112
QuestionColorFillBlend.iColor Issuememberpitoloko15 Jan '13 - 2:20 
Hello,
 
If I have a button with this palette:
 
            Button_Split.ColorFillBlend.iColor(0) = Color.GreenYellow
            Button_Split.ColorFillBlend.iColor(1) = Color.YellowGreen
            Button_Split.ColorFillBlend.iColor(2) = Color.DarkGreen
 
And then in execution time I change the colors to this:
 
        Button_Split.ColorFillBlend.iColor(0) = Color.White
        Button_Split.ColorFillBlend.iColor(1) = Color.Red
        Button_Split.ColorFillBlend.iColor(2) = Color.DarkRed
 
Then when I "hovermouse/focus" over the button, the color stills green instead of red
 
How I can solve this?
 
PS: Sorry for my english
AnswerRe: ColorFillBlend.iColor IssuememberSSDiver211215 Jan '13 - 13:24 
The Dim colors are not getting refreshed when you just change the iColor, so you have to force the refresh.
 
There are different ways to handle this. Some more complicated than others. The Dimmed colors (_HoverColorBlend...) could be moved into the class and updated as the iColor changes, or using the iNotify...
 
For some simple options you could make this change in the CButton.vb file:
Private Sub UpdateDimBlends() to ---> Public Sub UpdateDimBlends()
Then change the color like this:
        Button_Split.ColorFillBlend.iColor(0) = Color.White
        Button_Split.ColorFillBlend.iColor(1) = Color.Red
        Button_Split.ColorFillBlend.iColor(2) = Color.DarkRed
        Button_Split.UpdateDimBlends()
 
OR if you do not want to change the control code at all you can do it this way:
        Button_Split.ColorFillBlend = New CButtonLib.cBlendItems(
                                  New Color() {Color.White,
                                               Color.Red,
                                               Color.DarkRed},
                                  New Single() {Button_Split.ColorFillBlend.iPoint(0),
                                                Button_Split.ColorFillBlend.iPoint(1),
                                                Button_Split.ColorFillBlend.iPoint(2)})
 
Hope this helped.
 
SSDiver2112
GeneralRe: ColorFillBlend.iColor Issuememberpitoloko15 Jan '13 - 22:20 
Thankyou, i've choosed the first way.
 
I think this is the last questien after all, I appreciate so much your support.
 
[OFFTOPIC] There is a link where I can get all your extended controls? [/OFFTOPIC]
GeneralRe: ColorFillBlend.iColor IssuememberSSDiver211216 Jan '13 - 3:10 
Click on the SSDiver2112 Link next to this reply and then choose Articles Submitted.
 
Here is the link to make it easier
http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=2490950[^]
QuestionPerformClick() does nothingmemberpitoloko12 Jan '13 - 6:28 
Hello,
 
I can't do this:
 
If "a" = "a" then Cbutton1.PerformClick()
 
I can write the method without any exception, but the button isn't clicked
 
That means I can't use the button like this:
1. A "search bar" + "OnKeyPress" (Enter)
2. When ENTER key is pressed then "Button.performClick"
 
The method isn't implemented in the source code?
 
Thanks for read.
AnswerRe: PerformClick() does nothingmemberSSDiver211212 Jan '13 - 7:39 
I cannot say why you are having trouble. I put this in the Form1 code of the article demo and it works fine.
 
 
    Private Sub CButton1_ClickButtonArea(Sender As Object, e As MouseEventArgs) _
        Handles CButton1.ClickButtonArea
 
        If "a" = "a" Then CButtonON.PerformClick()
 
    End Sub
 
SSDiver2112
GeneralRe: PerformClick() does nothingmemberpitoloko12 Jan '13 - 7:54 
I've tried your same example but does nothing:
 
Public Class Form1
 
    Private Sub CButton1_ClickButtonAre(Sender As Object, e As MouseEventArgs) Handles CButton1.Click
        MsgBox("a")
    End Sub
 
    Private Sub CButton1_ClickButtonArea(Sender As Object, e As MouseEventArgs) Handles CButton1.ClickButtonArea
        If "a" = "a" Then CButton1.PerformClick()
    End Sub
 
End Class
 
If i add this to the form:
 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        CButton1.PerformClick()
    End Sub
 
Then i get an exception:
System.StackOverflowException was unhandled
 

PS: I'm using VS2012
GeneralRe: PerformClick() does nothingmemberSSDiver211212 Jan '13 - 8:36 
The error on the load is to be expected. Everything needs to be created first.
 
This code should toggle the CButtonON red and green.
    Private Sub CButton1_ClickButtonArea(Sender As Object, e As MouseEventArgs) _
        Handles CButton1.ClickButtonArea
 
        If "a" = "a" Then CButtonON.PerformClick()
 
    End Sub
 
I designed the button to use the not the Click event. The Click still works, but it will fire if you click the control anywhere and the ClickButtonArea only fires when you click the button part of the control (i.e. the Sponge Bob Button). If you did this:
    Private Sub Form1_Click(sender As Object, e As EventArgs) Handles Me.Click
        CButton1.PerformClick()
    End Sub
 
    Private Sub CButton1_Click(Sender As Object, e As MouseEventArgs) Handles CButton1.Click
        MsgBox("A")
    End Sub
 
    Private Sub CButton1_ClickButtonArea(Sender As Object, e As MouseEventArgs) Handles CButton1.ClickButtonArea
        MsgBox("B")
    End Sub
 
You will only see MessageBox "B"
If you are not seeing this behavior I cannot say at this point why.
 
If you need a work around until you get it figured out I would suggest putting all the button click code in a Sub:
    Private Sub Form1_Click(sender As Object, e As EventArgs) Handles Me.Click
        DoStuff()
    End Sub
    
    Private Sub CButton1_ClickButtonArea(Sender As Object, e As MouseEventArgs) Handles CButton1.ClickButtonArea
        DoStuff()
    End Sub
  
    Private Sub DoStuff()
        MsgBox("B")
    End Sub
 
SSDiver2112
GeneralRe: PerformClick() does nothingmemberpitoloko12 Jan '13 - 8:40 
All is right now, I understand, the click method is now the clickbuttonarea,
 
Thankyou again for your time, excellent control!
QuestionObject of type 'System.Int32' cannot be converted to type 'System.Int16'memberMember 396415919 Nov '12 - 23:13 
I am using the dll and now I am getting this error ,I develope application for green screen
and now I can not work on the app , I am using visual Basic 10 and I need to get it work
even for short time to remove the button and to replace them with standard button , the control looks good but I can not afford the problem like this andI am trying to reach the author last 2 weeeks ..please help email me back at samavakian@gmail.com. I did read the author fix but it is not clear were to put it and what if I am using the dll only , it was working before and for some reason start doing it even his sample app does it
AnswerRe: Object of type 'System.Int32' cannot be converted to type 'System.Int16'memberpitoloko11 Jan '13 - 5:32 
I have the same problem in VS2012, the DLL is incompatible when you try to change the colors, the Designer goes KABOOM, PLEASE SOMEONE IT'S TIME TO FIC THE PROBLEM,
 
PLEASE UPDATE THE SOURCE FOR US, SOMEONE PLEASE GIVE US A FIX!
GeneralRe: Object of type 'System.Int32' cannot be converted to type 'System.Int16'memberSSDiver211211 Jan '13 - 8:48 
I just added the 2012 version to the article download. This has the latest fixes and colorblender improvements. If you had an older version of the button and are changing to the new one and are still having issues with the designer it is because of the significant changes to the properties. It may be painful but you will either have to delete and/or update the offending designer errors or just delete all the button instances in the designer and then re-add the new button back onto the form. I had to do the this to all my older programs too, oh well the price of progress.
 
SSDiver2112
GeneralRe: Object of type 'System.Int32' cannot be converted to type 'System.Int16'memberpitoloko12 Jan '13 - 6:26 
Thankyou SO MUCH for your time!
 
EDIT: I've deleted my other comments, sorry for the spam but i was dessesperated, it's a great extended control!
QuestionUse in C#memberjojotjo5 Nov '12 - 6:59 
Can you drop the compiled dll also online please,
I want to use it in C#.
I'm using the old version now,
Wink | ;) that is also very good.
QuestionError on: Global.CButton.My.MySettings [modified]memberdherrmann25 Oct '12 - 10:07 
Hi,
 
I get the error on this line with: Global.CButton.My.MySettings
 
And then I get the following code in CButtonlib:
 
'------------------------------------------------------------------------------
' <auto-generated>
'     Dieser Code wurde von einem Tool generiert.
'     Laufzeitversion:4.0.30319.17929
'
'     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
'     der Code erneut generiert wird.
' </auto-generated>
'------------------------------------------------------------------------------

Option Strict On
Option Explicit On
 

Namespace My
    
    <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(),  _
     Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0"),  _
     Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)>  _
    Partial Friend NotInheritable Class MySettings
        Inherits Global.System.Configuration.ApplicationSettingsBase
        
        Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
        
#Region "Funktion zum automatischen Speichern von My.Settings"
#If _MyType = "WindowsForms" Then
    Private Shared addedHandler As Boolean
 
    Private Shared addedHandlerLockObject As New Object
 
    <Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
    Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)
        If My.Application.SaveMySettingsOnExit Then
            My.Settings.Save()
        End If
    End Sub
#End If
#End Region
        
        Public Shared ReadOnly Property [Default]() As MySettings
            Get
                
#If _MyType = "WindowsForms" Then
               If Not addedHandler Then
                    SyncLock addedHandlerLockObject
                        If Not addedHandler Then
                            AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
                            addedHandler = True
                        End If
                    End SyncLock
                End If
#End If
                Return defaultInstance
            End Get
        End Property
    End Class
End Namespace
 
Namespace My
    
    <Global.Microsoft.VisualBasic.HideModuleNameAttribute(),  _
     Global.System.Diagnostics.DebuggerNonUserCodeAttribute(),  _
     Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()>  _
    Friend Module MySettingsProperty
        
        <Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")>  _
        Friend ReadOnly Property Settings() As Global.CButton.My.MySettings
            Get
                Return Global.CButton.My.MySettings.Default
            End Get
        End Property
    End Module
End Namespace
 
How can I avoid this errors:
The type Global.CButton.My.MySettings is not defined.
and
"CButton" is not a member of "".
 
Regards
Dietrich

modified 25 Oct '12 - 17:01.

GeneralMy vote of 5memberpetervanekeren17 Oct '12 - 2:07 
Great usercontrol! Looks great and has a lot of options.
QuestionButton not curved ?memberclaudetom0114 Oct '12 - 10:30 
Excellent project!
Thank you for this control.
 
Is it possible to have a button with rounded corners but not as steep UpperRight values​​, etc. LowerLeft.
I tried different method to draw an angle instead of a bow, but the result is not at all convincing
 
Thank you
 

 
Essais :
Private Function GetRoundedRectPath(ByVal BaseRect As RectangleF) As GraphicsPath
 
        Dim ArcRect As RectangleF
        Dim MyPath As New Drawing2D.GraphicsPath()
        'MyPath.StartFigure()
        If Corners.All = -1 Then
            With MyPath
                ' top left arc
                If Corners.UpperLeft = 0 Then
                    .AddLine(BaseRect.X, BaseRect.Y, BaseRect.X, BaseRect.Y)
                Else
                    If CornersType = CornerType.Round Then
                        ArcRect = New RectangleF(BaseRect.Location, New SizeF(Corners.UpperLeft * 2, Corners.UpperLeft * 2))
                        .AddArc(ArcRect, 180, 90)
                    End If
                    If CornersType = CornerType.Ligne Then
                        '.AddLine(New PointF(BaseRect.X, BaseRect.Y + Corners.UpperLeft), New Point(BaseRect.X, Corners.UpperLeft))

                        .AddLine(New PointF(BaseRect.X, BaseRect.Y + Corners.UpperLeft), New Point(BaseRect.X, BaseRect.Y + Corners.UpperLeft))
                    End If
                End If
 
                ' top right arc
                If Corners.UpperRight = 0 Then
                    .AddLine(BaseRect.X + (Corners.UpperLeft), BaseRect.Y, BaseRect.Right - (Corners.UpperRight), BaseRect.Top)
                Else
                    If CornersType = CornerType.Round Then
                        ArcRect = New RectangleF(BaseRect.Location, New SizeF(Corners.UpperRight * 2, Corners.UpperRight * 2))
                        ArcRect.X = BaseRect.Right - (Corners.UpperRight * 2)
                        .AddArc(ArcRect, 270, 90)
                    End If
                    If CornersType = CornerType.Ligne Then
                        .AddLine(New PointF(BaseRect.X + Corners.UpperLeft, BaseRect.Y), New Point(BaseRect.Right - Corners.UpperRight, BaseRect.Top))
                    End If
                End If
 
                ' bottom right arc
                If Corners.LowerRight = 0 Then
                    .AddLine(BaseRect.Right, BaseRect.Top + (Corners.UpperRight), BaseRect.Right, BaseRect.Bottom - (Corners.LowerRight))
                Else
                    If CornersType = CornerType.Round Then
                        ArcRect = New RectangleF(BaseRect.Location, New SizeF(Corners.LowerRight * 2, Corners.LowerRight * 2))
                        ArcRect.Y = BaseRect.Bottom - (Corners.LowerRight * 2)
                        ArcRect.X = BaseRect.Right - (Corners.LowerRight * 2)
                        .AddArc(ArcRect, 0, 90)
                    End If
                    If CornersType = CornerType.Ligne Then
                        .AddLine(BaseRect.Right, BaseRect.Top + (Corners.UpperRight), BaseRect.Right, BaseRect.Bottom - (Corners.LowerRight))
                    End If
                End If
 
                ' bottom left arc
                If Corners.LowerLeft = 0 Then
                    .AddLine(BaseRect.Right - (Corners.LowerRight), BaseRect.Bottom, BaseRect.X - (Corners.LowerLeft), BaseRect.Bottom)
                Else
                    If CornersType = CornerType.Round Then
                        ArcRect = New RectangleF(BaseRect.Location, New SizeF(Corners.LowerLeft * 2, Corners.LowerLeft * 2))
                        ArcRect.Y = BaseRect.Bottom - (Corners.LowerLeft * 2)
                        .AddArc(ArcRect, 90, 90)
                    End If
                    If CornersType = CornerType.Ligne Then
                        '.AddLine(BaseRect.Right - (Corners.LowerRight), BaseRect.Bottom, BaseRect.X - (Corners.LowerLeft), BaseRect.Bottom)
                        .AddLine(BaseRect.Right - Corners.LowerLeft, BaseRect.Bottom, BaseRect.X + Corners.LowerLeft, BaseRect.Bottom)
                    End If
                End If
...

SuggestionRe: Button not curved ?memberclaudetom0116 Oct '12 - 8:54 
A ma question voici ma solution
 
 Private Function GetRoundedRectPath(ByVal BaseRect As RectangleF) As GraphicsPath
 
        Dim ArcRect As RectangleF
        Dim MyPath As New Drawing2D.GraphicsPath()
        If CornersType = CornerType.Ligne Then
            Return AddAnglesCorners(BaseRect)
        End If
...
Public Function AddAnglesCorners(ByVal BaseRect As RectangleF) As GraphicsPath
        Dim MyPath As New Drawing2D.GraphicsPath()
        Dim points(7) As Point
        'TopLeft 
        points(0) = New Point(CInt(BaseRect.Left + Corners.UpperLeft), CInt(BaseRect.Top))
        'TopRight
        points(1) = New Point(CInt(BaseRect.Right - Corners.UpperRight), CInt(BaseRect.Top))
        points(2) = New Point(CInt(BaseRect.Right), CInt(BaseRect.Top + Corners.UpperRight))
        'BottomRight
        points(3) = New Point(CInt(BaseRect.Right), CInt(BaseRect.Bottom - Corners.LowerRight))
        points(4) = New Point(CInt(BaseRect.Right - Corners.LowerRight), CInt(BaseRect.Bottom))
        'BottomLeft
        points(5) = New Point(CInt(BaseRect.Left + Corners.LowerLeft), CInt(BaseRect.Bottom))
        points(6) = New Point(CInt(BaseRect.Left), CInt(BaseRect.Bottom - Corners.LowerLeft))
        'TopLeft
        points(7) = New Point(CInt(BaseRect.Left), CInt(BaseRect.Top + Corners.UpperLeft))
        With MyPath
            .AddLines(points)
            .CloseFigure()
        End With
        Return MyPath
    End Function

GeneralMy vote of 5memberTamok5 Oct '12 - 14:45 
I have been using this control for several months without any problems. It provides some customization that makes my application unique. Thanks!
SuggestionCannot convert Integer errors when trying to load a form with the button in the designer resolvedmemberPatLaf2 Oct '12 - 9:30 
I see a lot of questions asking for help dealing with "The object of type System.Int32 can not be converted to an object System.Int16". I believe this is happening because the designer needs to run the Initialization code for the control at design time. Given this belief I went in and for every public property in the cbutton.vb module I added the line of code below, cleaned and recompiled the cButton project, cleaned my test app and voila, it works as advertised and the sample app included with the project now loads the form at design time with no errors.
 
<System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)> _
 
I'm using VS2010 and I recompiled targeting .net framework 4.0 but I've also used VS2012 and targeted the 4.5 framework with the same success.
 

HTH
Pat
GeneralRe: Cannot convert Integer errors when trying to load a form with the button in the designer resolvedmemberPatLaf2 Oct '12 - 9:33 
I forgot to mention that you will have to code for all those properties in your app because they will no longer appear in the designers property window. Kind of a bummer but IMHO a better solution than the 68 errors I was getting Smile | :)

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 11 Jan 2013
Article Copyright 2008 by SSDiver2112
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid