Jump to content
Xtreme .Net Talk

Recommended Posts

  • *Experts*
Posted

I have little to no experience on programming gradients or programming graphics for that matter, but have been digitally drawing them for bunches of years. I have moved up to a level of mass confusion while searching the net for examples of how to paint a gradient on a popup style button. I would appreciate any help on this.

 

Thanks

Dan

Member, in good standing, of the elite fraternity of mentally challenged programmers.

 

Dolphins Software

  • *Experts*
Posted

It's probably more trouble than it's worth. Making your own button

control that supports gradients would be much simpler, most likely.

  • *Experts*
Posted

Hi divil, Here's what I have so far that produces nothing:

 

Private Sub Button1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Button1.Paint

 

PaintGradient(Color.AliceBlue, Color.SteelBlue, Drawing.Drawing2D.LinearGradientMode.Vertical)

End Sub

 

Private Sub PaintGradient(ByVal TopColor As Color, ByVal BottomColor As Color, ByVal mode As System.Drawing.Drawing2D.LinearGradientMode)

 

Dim a As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, Me.Width, Me.Height), TopColor, BottomColor, mode)

Dim g As Graphics = Me.CreateGraphics

g.FillRectangle(a, New RectangleF(0, 0, Me.Width, Me.Height))

g.Dispose()

End Sub

 

Thanks

Dan

Member, in good standing, of the elite fraternity of mentally challenged programmers.

 

Dolphins Software

Posted

Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Data
Imports System.Windows.Forms
Imports System.ComponentModel.Design.Serialization

Namespace Usercontrols

   Public Class gradiant_button
       Inherits System.Windows.Forms.Button

       Private _OutlineColor As Color = Color.White
       Private _FillColor As Color = Color.Gray
       Private _FillColor_Gradiant As Color = Color.SteelBlue
       Private _FillColorDisabled As Color = Color.LightGray
       Private _FillColorDisabled_Gradiant As Color = Color.Gray
       Private _FillColorHover As Color = Color.Beige
       Private _FillColorHover_Gradiant As Color = Color.Beige
       Private _TextColor As Color = Color.Black
       Private _TextColor_Gradiant As Color = Color.Black
       Private SwapMouse As Boolean = False
       Private DownMouse As Boolean = False

#Region "Coloring code & Properties"

       Public Property FillColor() As Color
           Get
               Return _FillColor
           End Get
           Set(ByVal Value As Color)
               _FillColor = Value
               Invalidate()
           End Set
       End Property

       Public Property FillColor_Gradiant() As Color
           Get
               Return _FillColor_Gradiant
           End Get
           Set(ByVal Value As Color)
               _FillColor_Gradiant = Value
               Invalidate()
           End Set
       End Property

       Public Property FillColorDisabled() As Color
           Get
               Return _FillColorDisabled
           End Get
           Set(ByVal Value As Color)
               _FillColorDisabled = Value
               Invalidate()
           End Set
       End Property

       Public Property FillColorDisabled_Gradiant() As Color
           Get
               Return _FillColorDisabled_Gradiant
           End Get
           Set(ByVal Value As Color)
               _FillColorDisabled_Gradiant = Value
               Invalidate()
           End Set
       End Property

       Public Property FillColorHover() As Color
           Get
               Return _FillColorHover
           End Get
           Set(ByVal Value As Color)
               _FillColorHover = Value
               Invalidate()
           End Set
       End Property

       Public Property FillColorHover_Gradiant() As Color
           Get
               Return _FillColorHover_Gradiant
           End Get
           Set(ByVal Value As Color)
               _FillColorHover_Gradiant = Value
               Invalidate()
           End Set
       End Property

       Public Property TextColor() As Color
           Get
               Return _TextColor
           End Get
           Set(ByVal Value As Color)
               _TextColor = Value
               Invalidate()
           End Set
       End Property

       Public Property TextColor_Gradiant() As Color
           Get
               Return _TextColor_Gradiant
           End Get
           Set(ByVal Value As Color)
               _TextColor_Gradiant = Value
               Invalidate()
           End Set
       End Property

#End Region

#Region " Windows Form Designer generated code "

       Public Sub New()
           MyBase.New()
           'This call is required by the Windows Form Designer.
           InitializeComponent()
           'Add any initialization after the InitializeComponent() call
           SetStyle(ControlStyles.AllPaintingInWmPaint, True)
           SetStyle(ControlStyles.DoubleBuffer, True)
           SetStyle(ControlStyles.ResizeRedraw, True)
       End Sub

       'UserControl overrides dispose to clean up the component list.
       Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
           If disposing Then
               If Not (components Is Nothing) Then
                   components.Dispose()
               End If
           End If
           MyBase.Dispose(disposing)
       End Sub

       'Required by the Windows Form Designer
       Private components As System.ComponentModel.IContainer

       'NOTE: The following procedure is required by the Windows Form Designer
       'It can be modified using the Windows Form Designer.  
       'Do not modify it using the code editor.
       <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
           '
           'outline_button
           '
           Me.Name = "outline_button"
           Me.Size = New System.Drawing.Size(62, 62)
       End Sub

#End Region

#Region "Paint and Mouse"

       Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
           Dim GradiantBrush As Brush
           Dim TextBrush As Brush
           Dim HoverBrush As Brush
           Dim DisabledBrush As Brush
           Dim StringSize As New SizeF()

           ' Setup gradiants into the brushes 3, Text, Hover, Normal
           HoverBrush = New Drawing2D.LinearGradientBrush(New Point(0, 0), New Point(0, Me.Height), Me.FillColorHover, Me.FillColorHover_Gradiant)
           GradiantBrush = New Drawing2D.LinearGradientBrush(New Point(0, 0), New Point(0, Me.Height), Me._FillColor, Me._FillColor_Gradiant)
           TextBrush = New Drawing2D.LinearGradientBrush(New Point(0, 0), New Point(0, Me.Height), Me._TextColor, Me._TextColor_Gradiant)
           DisabledBrush = New Drawing2D.LinearGradientBrush(New Point(0, 0), New Point(0, Me.Height), Me._FillColorDisabled, Me._FillColorDisabled_Gradiant)

           ' if mouse hovering
           If Me.Enabled Then
               If Me.SwapMouse = True Then
                   e.Graphics.FillRectangle(HoverBrush, ClientRectangle)
               Else
                   e.Graphics.FillRectangle(GradiantBrush, ClientRectangle)
               End If
           Else
               e.Graphics.FillRectangle(DisabledBrush, ClientRectangle)
           End If

           ' if mouse button down change border style
           If Me.DownMouse = True And Me.Enabled Then
               ControlPaint.DrawBorder3D(e.Graphics, ClientRectangle, Border3DStyle.Bump)
           Else
               ControlPaint.DrawBorder3D(e.Graphics, ClientRectangle, Border3DStyle.Etched)
           End If

           ' text centred in button
           StringSize = e.Graphics.MeasureString(Text, Font)
           e.Graphics.DrawString(Text, Font, TextBrush, Convert.ToInt32(Width / 2) - Convert.ToInt32(StringSize.Width / 2), Convert.ToInt32(Height / 2) - Convert.ToInt32(StringSize.Height / 2))
       End Sub

#Region "Mouse events"

       Protected Overrides Sub OnMouseLeave(ByVal e As System.EventArgs)
           Me.SwapMouse = False
           Me.Refresh()
           MyBase.OnMouseLeave(New EventArgs())
       End Sub

       Protected Overrides Sub OnMouseEnter(ByVal e As System.EventArgs)
           Me.SwapMouse = True
           Me.Refresh()
           MyBase.OnMouseEnter(New EventArgs())
       End Sub

       Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
           Me.DownMouse = True
           Me.Refresh()
           MyBase.OnMouseDown(e)
       End Sub

       Protected Overrides Sub OnMouseUp(ByVal e As System.Windows.Forms.MouseEventArgs)
           Me.DownMouse = False
           Me.Refresh()
           MyBase.OnMouseUp(e)
       End Sub

#End Region

#End Region

       Protected Overrides Sub OnValidated(ByVal e As System.EventArgs)
           Me.Refresh()
       End Sub

   End Class

End Namespace

 

This is a fairly simple user control with gradiants with hover and text gradiants.

 

to use Click on project->Add user control

 

and paste the code

 

and use

 

 

Andy

Code today gone tomorrow!
Posted

Hi Diverdan..

 

You are on the right track, but you've missed one imported thing:

 

Private Sub Button1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Button1.Paint

PaintGradient(Color.AliceBlue, Color.SteelBlue, Drawing.Drawing2D.LinearGradientMode.Vertical,e.Graphics,sender)
End Sub

Private Sub PaintGradient(ByVal TopColor As Color, ByVal BottomColor As Color, ByVal mode As System.Drawing.Drawing2D.LinearGradientMode,g as Graphics,target as Control)

Dim a As New System.Drawing.Drawing2D.LinearGradientBrush(New RectangleF(0, 0, target.Width, target.Height), TopColor, BottomColor, mode)

g.FillRectangle(a, New RectangleF(0, 0, target.Width, target.Height))
g.Dispose()
End Sub

 

You can see I've only added a graphics object to your function, rather than creating one in the function... (by the way, youve created a graphics surface of your form, not the button)

I've also added a control parameter to the function that will determine the size of the area/rectangle..

 

So you can see that you were close... :)

Howzit??
  • *Experts*
Posted

Be careful when you call Dispose() on a Graphics object. Cywizz, your example is not creating the Graphics object and therefore shouldn't Dispose of it. Only when you create one through CreateGraphics should you Dispose of it.

 

-Nerseus

"I want to stand as close to the edge as I can without going over. Out on the edge you see all the kinds of things you can't see from the center." - Kurt Vonnegut
Posted

good spot... I just copied dd's code and added the parameters, but you are right, it usually also generates a error when trying to do so.

The brush (a) should be disposed of in the above example.

 

(Pens, brushes and Graphic objects must be disposed if created)

 

Cheers... :)

Howzit??
  • *Experts*
Posted (edited)

I ended up making a few mods on Andy's code to also indent the text a bit on mouse down.

 

       StringSize = e.Graphics.MeasureString(Me._Text, Me.textFont)

       ' if mouse button down change border style
       If Me.DownMouse = True Then
           ControlPaint.DrawBorder3D(e.Graphics, ClientRectangle, Border3DStyle.Bump)
           e.Graphics.DrawString(Me._Text, Me.textFont, TextBrush, Convert.ToInt32(Me.Width / 2) - Convert.ToInt32(StringSize.Width / 2) + 1, Convert.ToInt32(Me.Height / 2 + 1) - Convert.ToInt32(StringSize.Height / 2) + 1 / 2)
       Else
           ControlPaint.DrawBorder3D(e.Graphics, ClientRectangle, Border3DStyle.Etched)
           e.Graphics.DrawString(Me._Text, Me.textFont, TextBrush, Convert.ToInt32(Me.Width / 2) - Convert.ToInt32(StringSize.Width / 2), Convert.ToInt32(Me.Height / 2) - Convert.ToInt32(StringSize.Height / 2))
       End If

 

Sorry, I'm still a bit old fashioned and still like to see the button and text move together.

 

I think this User control is pretty nice!!! Thanks again Andy!

 

The only thing it now lacks is TabIndex support, which would be really nice.

 

Thanks again

Dan

Edited by divil

Member, in good standing, of the elite fraternity of mentally challenged programmers.

 

Dolphins Software

  • *Experts*
Posted (edited)

Thanks Andy, this is looking great!

 

Although I'm having a problem loading your class into my project?

 

I'm getting the following error message:

 

The user control gradient_button could not be loaded. Ensure that the library containing the control has been built and a project reference has been made to the library containg the control. If you have changed the name of the user control , close and re-open then control's desigener to update the toolbox item.

 

I really like your gradient button and would like to use it in my projects. Please help.

 

I changed the dash "focus " line a bit to put it to the outside regions of the button to be less obstrusive to the gradient:

 

Dim OutlinePen As New Pen(ForeColor)

OutlinePen.DashStyle = DashStyle.Dot

If (Me.DownMouse = True And Me.Enabled) Then

'e.Graphics.DrawRectangle(OutlinePen, 10, 10, Me.Width - 16, Me.Height - 16)

e.Graphics.DrawRectangle(OutlinePen, 3, 3, Me.Width - 6, Me.Height - 6)

Else

'e.Graphics.DrawRectangle(OutlinePen, 8, 7, Me.Width - 16, Me.Height - 15)

e.Graphics.DrawRectangle(OutlinePen, 2, 2, Me.Width - 6, Me.Height - 6)

End If

OutlinePen.Dispose()

End If

 

and changed the text offset back to:

 

' if mouse button down change border style

If (Me.DownMouse = True And Me.Enabled) Then

ControlPaint.DrawBorder3D(e.Graphics, ClientRectangle, Border3DStyle.Bump)

e.Graphics.DrawString(Text, Font, TextBrush, Convert.ToInt32(Width / 2) - Convert.ToInt32(StringSize.Width / 2) + 1, Convert.ToInt32(Height / 2) - Convert.ToInt32(StringSize.Height / 2) + 1 / 2)

Else

ControlPaint.DrawBorder3D(e.Graphics, ClientRectangle, Border3DStyle.Etched)

e.Graphics.DrawString(Text, Font, TextBrush, Convert.ToInt32(Width / 2) - Convert.ToInt32(StringSize.Width / 2), Convert.ToInt32(Height / 2) - Convert.ToInt32(StringSize.Height / 2))

End If

 

I guess these changes reflect the artist side of me, sorry but it's there.

 

 

I'm only useing VB.Net Standard :-( and cannot complie this control into a dll. With these modifications, I think this gradient button control is perfect. Maybe a dll would work better simular to divil's widgets, which is also a great control.

 

Thanks

Dan

Edited by DiverDan

Member, in good standing, of the elite fraternity of mentally challenged programmers.

 

Dolphins Software

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...