Solved

Gradient bitmaps and the paint event

Posted on 2006-06-14
15
984 Views
Last Modified: 2012-06-27
I have a form with the background image set to a gradient image. On the form is docked a splitcontainer with all of the appropriate backcolor properties set to color.transparent

Problem is that if I resize or change the orientation of the split, it appears as if the paint event fires numerous times. It also doesn't repaint the actual gradient region, but rather flashes multiple times in the main graident color.

So my question is, is there a way to foce or control the paint event so that any resizing, repainting, etc, appears seemless.

i've tried double buffering, suspend layout, setting the visible property, etc, to no avail - always flashes.

Note - if the form's back color is just set to a solid backcolor (no backimage) then refreshing/painting is pretty smotth. It's oly whne the background cointains an image that multiple redraws seem to rake place.

???

Thanks.
0
Comment
Question by:carpbyte
  • 8
  • 5
15 Comments
 
LVL 7

Expert Comment

by:5thcav
ID: 17024369
set a boolen when resizing to true and when the mouse up event fires then repaint
0
 
LVL 7

Expert Comment

by:5thcav
ID: 17024377
also when mouse down on the resizing set the background to stretch

hay,, just put your controls on a picturebox and the gradient will simple stretch..

i see that you posted a while ago,, i was searching to apply a gradient to a bmp ,,

maybe you can still use the help?
0
 

Author Comment

by:carpbyte
ID: 17047047
Thanks, but still no luck.

Same issue - whatever the control's backcolor is set to is what flashes.

A boolean won't work because there is NO code in the actual paint event - it's whatever the default "painting" that .NET uses is what seems to be causing the problem.

Carp
0
 
LVL 7

Expert Comment

by:5thcav
ID: 17047604

try this,,,,

Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.ResizeRedraw Or ControlStyles.UserPaint Or ControlStyles.OptimizedDoubleBuffer, True) : Me.UpdateStyles()


maybe set color.transparent to white during the drag?
0
 

Author Comment

by:carpbyte
ID: 17052367
Nope, same thing, flash of default backcolor.

I am having some luck with the following though, but it's been awhile so I've kind of forgotten what I was initially trying to do...need to redefine the problem...

Thanks for the comments.

Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)

    If Me.BackgroundImage Is Nothing Then
      If Not (Parent.BackgroundImage Is Nothing) Then
        e.Graphics.DrawImage(Parent.BackgroundImage, _
          New Rectangle(0, 0, Me.Width, Me.Height), _
          Me.Left, Me.Top, Me.Width, Me.Height, GraphicsUnit.Pixel)
      Else
        e.Graphics.FillRectangle(New SolidBrush(Parent.BackColor), _
        New Rectangle(0, 0, Me.Width, Me.Height))
      End If
    End If

    Dim attributes As New ImageAttributes

    Dim matrixElements As Single()() = { _
      New Single() {1.0F, 0.0F, 0.0F, 0.0F, 0.0F}, _
      New Single() {0.0F, 1.0F, 0.0F, 0.0F, 0.0F}, _
      New Single() {0.0F, 0.0F, 1.0F, 0.0F, 0.0F}, _
      New Single() {0.0F, 0.0F, 0.0F, CSng(_opacity), 0.0F}, _
      New Single() {0.0F, 0.0F, 0.0F, 0.0F, 1.0F}}

    Dim matrix As ColorMatrix
    matrix = New ColorMatrix(matrixElements)
    attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap)

    Dim bitmap As Bitmap = New Bitmap(Me.Width, Me.Height, PixelFormat.Format24bppRgb)
    Dim g As Graphics = Graphics.FromImage(bitmap)
    Dim brush As Brush = New SolidBrush(Me.BackColor)
    g.FillRectangle(brush, New RectangleF(0, 0, Me.Width, Me.Height))
    brush.Dispose()
    e.Graphics.DrawImage(bitmap, _
      New Rectangle(0, 0, Me.Width, Me.Height), _
      0, 0, Me.Width, Me.Height, GraphicsUnit.Pixel, attributes)

  End Sub
0
 
LVL 7

Expert Comment

by:5thcav
ID: 17055332
    just make a bmp from the code below and set the background to the image?
     set the picturebox or panel? background to stretch.

its going to flash if its in the onpaint event, maybe put your code into a timer event or resize event.

does painting during the onpaint event cause the onpaint event to fire? when you think of it this way
it sure shounds like i know what im doing! LOL

   Dim r As Rectangle
        Dim b As LinearGradientBrush
        r = New Rectangle(0, 0, Me.Width, Me.Height)
        b = New LinearGradientBrush(r, Color.Blue, Color.LightBlue, LinearGradientMode.Vertical)
        e.Graphics.FillRectangle(b, r)
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 7

Expert Comment

by:5thcav
ID: 17055335
picturebox image, not background
0
 

Author Comment

by:carpbyte
ID: 17126682
OK I Made a simple test app to show what the issue is without using a bitmap. The issue is the same.

I'm also bumping up the points because I really need to figure this out in VB.net

If you try the following, the Picture box will show the parent form's backcolor and NOT the gradient (which is what I want..)

Any help would be appreciated. I have a feeling I somehow need to grab the painted region from memory and work some API magic to get thsi to work.

Thanks.

Create a Form and set it's back color to Red

In the Load Event:

        Dim pic As New PictureBox
        pic.BackColor = Color.Transparent 'want the gradient to show through
        pic.BorderStyle = BorderStyle.FixedSingle
        Me.Controls.Add(pic)
In the Paint Event:

        Dim gr As Graphics = Me.CreateGraphics
        Dim brSize As Rectangle = New Rectangle(0, 0, Me.Width, Me.Height)
        Dim clrs() As String = {"255", "0", "0", "255"}
        Dim clr As Color = Color.FromArgb(clrs(0), clrs(1), clrs(2), clrs(3))
        Dim lgBrush As New LinearGradientBrush(brSize, clr, Color.Black, LinearGradientMode.Vertical)
        Dim br As Brush = lgBrush

        gr.FillRectangle(br, 0, 0, Me.Width, Me.Height) ' Fill the entire Control/Form
        br.Dispose()
        lgBrush.Dispose()
        gr.Dispose()

0
 
LVL 7

Expert Comment

by:5thcav
ID: 17127098
this works for me?

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
       
        Dim pic As New PictureBox
        pic.BackColor = Color.Transparent
        pic.BorderStyle = BorderStyle.FixedSingle
        Me.Controls.Add(pic)
        pic.Dock = DockStyle.Fill
        pic.BackgroundImageLayout = ImageLayout.Stretch
        Dim bmp As Bitmap
        bmp = New Bitmap(Width, Height, Imaging.PixelFormat.Format24bppRgb)
        Dim gr As Graphics = Graphics.FromImage(bmp)
        Dim brSize As Rectangle = New Rectangle(0, 0, 800, 600)
        Dim clrs() As String = {"255", "0", "0", "255"}
        Dim clr As Color = Color.FromArgb(clrs(0), clrs(1), clrs(2), clrs(3))
        Dim lgBrush As New Drawing2D.LinearGradientBrush(brSize, clr, Color.Black, Drawing2D.LinearGradientMode.Vertical)
        Dim br As Brush = lgBrush
        gr.FillRectangle(br, 0, 0, 800, 600)
        pic.BackgroundImage = bmp

        Dim pic1 As New PictureBox
        pic1.BackColor = Color.Transparent
        pic1.BorderStyle = BorderStyle.FixedSingle
        Me.Controls.Add(pic1)
        pic1.BringToFront()
        br.Dispose()
        lgBrush.Dispose()
        gr.Dispose()
    End Sub
0
 

Author Comment

by:carpbyte
ID: 17132376
Not for me.

I get a grey rectangle in the upper left corner, NOT a transparent picture control displaying the gradient underneath.

?
0
 
LVL 7

Expert Comment

by:5thcav
ID: 17135084
shows red for me? did you set

did you set the forms backcolor to red.

this would have to be the case if you see gray. thats the only place it can come from..
0
 

Author Comment

by:carpbyte
ID: 17135103
That's not what I'm looking for, that's the problem.

Whatever the BackColor is of the Form ISwhat's showing through - I don't want that, I want the GRADIENT that was created in the form's paint event to show through, NOT the back color.

Same problem if the form has a background image - the iumage won't show through, only the back color.

I think it's a bug...
0
 
LVL 7

Accepted Solution

by:
5thcav earned 500 total points
ID: 17135161
got it!

pic1.Parent = pic
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray. The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Ru…
I think the Typed DataTable and Typed DataSet are very good options when working with data, but I don't like auto-generated code. First, I create an Abstract Class for my DataTables Common Code.  This class Inherits from DataTable. Also, it can …
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now