OnPaint Event for Form (1 Viewer)

Adelina_RO

Member
Local time
Today, 07:16
Joined
Apr 9, 2021
Messages
42
Hi people :)
Basically i have one question: why does Access repaint each row by a random number of times and in a random order? (Are those two questions... :unsure:)
Here is the layout: i have a continuous form where, in the OnPaint event i do some stuff (format some textboxes based on values in the underlying recordset (ADO)). The thing is, every row is painted multiple times whenever i click on an invisible button that's covering the textboxes. When the forms loads, every row is painted 5 times (with the first 3 rows being painted another time), when i click the invisible button, each visible row is painted 4 times.
I've tested this in an unbound form who gets its recordset set in the OnLoad event. So there are no rows to be painted before the last line in the on_load...
I'm stomped, especially since there are no good info on the OnPaint event, safe for a few, but even those are for Reports...
I wouldn't care less about how many times Access decides to paint, but i have a flicker and it may be from this?

P.S. I read that in vb.net there is a double-buffering option to remove screen flicker. Is this also possible for Access?
 

June7

AWF VIP
Local time
Yesterday, 20:16
Joined
Mar 9, 2014
Messages
5,471
Have you tried Conditional Formatting instead?
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 00:16
Joined
Feb 19, 2002
Messages
43,275
The Paint event is not appropriate for what you are doing. Use the Format event. It runs once EXCEPT that since Access formats a row before it knows if there is room to print it on the page, If there is no room on the current page, the Retreat event runs, the report footer is formatted, the report header and group headers are formatted, then the detail section is formatted again. You can tell by the FormatCount property whether the event is running for the first time or a subsequent time.

Here's a link with a little more detail.

 
Last edited:

June7

AWF VIP
Local time
Yesterday, 20:16
Joined
Mar 9, 2014
Messages
5,471
OP said this is a form, not report.
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 00:16
Joined
Feb 19, 2002
Messages
43,275
OK. The paint event of the FORM is not appropriate for whatever you are trying to do.

As June suggested, Conditional Formatting is used for formatting. It was introduced to get around the problem of trying to format a continuous or DS view form.

The flicker is caused by the code being in the Paint event and running multiple times.
 

Isaac

Lifelong Learner
Local time
Yesterday, 21:16
Joined
Mar 14, 2017
Messages
8,777
I just had to read this thread, as I've never heard of anyone using the OnPaint event - and didn't even notice it existed until today.
Thanks for teaching me something new :geek:
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 00:16
Joined
May 21, 2018
Messages
8,529
The On_paint event in a form has limited. It can be used in places when you need to format something that CF does not. But even that is problematic. The on paint event fires excessively with any interaction. Almost any movement of the scroll bar will cause it to fire. You can test this by putting a msgbox in the on paint and see how many times you have to click on it. A report has less interaction so this works fine for a lot of things.
Here is an example (no real utility) of using the on paint to change the color of a line randomly on the on_paint event.
 

Attachments

  • ChangeFormat.accdb
    992 KB · Views: 337

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Yesterday, 23:16
Joined
Feb 28, 2001
Messages
27,186
Interesting... the Form_OnPaint event is not listed in the Microsoft documentation. Nor is a Paint event listed. So I went into Object Browser and looked at the events listed for Access Form objects. Neither .Paint nor .OnPaint is listed.


Is this a case when an event becomes available if & only if you are doing something specific with the form? Sort of like the fact that OnCurrent does not exist for unbound forms but if you bind it, OnCurrent suddenly shows up?
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Yesterday, 23:16
Joined
Feb 28, 2001
Messages
27,186
Thanks. I found Section.Paint but the reference I found suggested that it was only a report section event. Sometimes MS has multiple different references online from different year-versions of Office and it is hard to tell what applies when.

I would think that a section will take an OnPaint with each Me.Repaint - which is implied by things like Me.Requery as well as actions that change the status of a control in a way that requires at least a partial repaint. So I guess it WOULD be a busy event.
 

Adelina_RO

Member
Local time
Today, 07:16
Joined
Apr 9, 2021
Messages
42
Well, first of all, i'm super happy i got all of you to answer - Thank you!
The thing is, i used to use Conditional Formatting, but i have quite a few dynamic conditions which I would change on FormLoad. i don't like that approach since i still get the flicker and if the user scrolls fast enough they have quite some lag. Besides, in the Paint event you can change much more than just CF options.
So i take it that there is no right way to do this as to avoid The Flicker (sounds like a horror movie title)...
I read somewhere that the problem might be that Access is painting twice or more times over the same pixel - which is my case, but i have no idea on how to overcome that..
 

Adelina_RO

Member
Local time
Today, 07:16
Joined
Apr 9, 2021
Messages
42
The On_paint event in a form has limited. It can be used in places when you need to format something that CF does not. But even that is problematic. The on paint event fires excessively with any interaction. Almost any movement of the scroll bar will cause it to fire. You can test this by putting a msgbox in the on paint and see how many times you have to click on it. A report has less interaction so this works fine for a lot of things.
Here is an example (no real utility) of using the on paint to change the color of a line randomly on the on_paint event.
i looked at your example and it works, but you only format a line's back color. That works as intended since, first it changes only on property of one control and it's not overlapped with other controls... i need smth more complex.
I've attached a sample to give you an idea
 

Attachments

  • xxx.accdb
    896 KB · Views: 301

MajP

You've got your good things, and you've got mine.
Local time
Today, 00:16
Joined
May 21, 2018
Messages
8,529
that works as intended since, first it changes only on property of one control and it's not overlapped with other controls... i need smth more complex.
That was not meant to be a solution, but the opposite. It was to demo how often the repaint takes place, to demo a case where CF does not work, and to reiterate that you should be using CF.
I am surprised this works as well as it does. I am running a pretty fast computer and do not see the issues you point out. Conversely everything I see you doing can be done with CF. Try it and see if you get a better output.
I do not believe the following is true and should be testable.
It runs once EXCEPT that since Access formats a row before it knows if there is room to print it on the page,
In fact, I think it actually runs just as much as the on paint. CF would have to run on every on paint event.
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 00:16
Joined
May 21, 2018
Messages
8,529
But going back to your original thread is this just a question about how things are repainted and how often, or is there a problem? For me your example works as well or better than what I would get with CF. IMO CF is just a wrapper around the on paint. Nothing really different except a user interface to program it.
But if you think about it, There is one set of controls and all records in a continuous form are nothing by "paint". So every time you scroll, update a vaule, execute a function, etc, it forces a repaint. It may be a little repetitive to ensure all cases are covered, but it is not "random".
 

isladogs

MVP / VIP
Local time
Today, 05:16
Joined
Jan 14, 2017
Messages
18,221
@Adelina_RO
I can't see anything in your Paint event code that can't be done using CF.
Just wondering why you think otherwise
 

Adelina_RO

Member
Local time
Today, 07:16
Joined
Apr 9, 2021
Messages
42
as you've seen, i have both options: OnPaint and CF. For me, OnPaint is slightly easier on the eye, but still...
LE: i found that i can do a combination of both: i use CF for the one time painted controls (like those colored ones) and OnPaint to highlight the current row. Even faster and with less flicker is if i use a rectangle control instead of a textbox for highlighting.
in the end, i was hoping that there was a way with 0 (zero) flicker, but as i'm getting fed up with this (non) issue, i will settle for what i can get.
@MajP : you are right - it is not random, it does the same amount of repainting.
@isladogs : indeed, but CF is way laggier for me

To sum this up: thank you everyone and we can consider this thread closed. I've decided that, when i'll have more time, i'll covert everything to vb.net :)))
 

isladogs

MVP / VIP
Local time
Today, 05:16
Joined
Jan 14, 2017
Messages
18,221
@isladogs : indeed, but CF is way laggier for me

To sum this up: thank you everyone and we can consider this thread closed. I've decided that, when i'll have more time, i'll covert everything to vb.net :)))
Well I disagree ... but have you tried the standard method of reducing flicker?
Try modifying your Paint event to

Code:
Private Sub Detail_Paint()
If Not Parent!DP Then Exit Sub

Application.Echo False

'the rest of your code here

Application.Echo True

End Sub

Does that help at all?
 
Last edited:

MajP

You've got your good things, and you've got mine.
Local time
Today, 00:16
Joined
May 21, 2018
Messages
8,529
I have almost no flicker on my machine. It is more like a very quick flash. Is that what you are talking about?
If you have to get rid of this, I guess I would do an unbound form.
You have 8 columns. Lets say you have 20 rows then 160 controls not to painful. You can write some code to give them all a consistent naming convention to be used in coding. Then you have your own controls to load 20 records at a time. (next 20, previous 20). Then you color the controls. This is less work then porting it to .net but not trivial. I have some code to simplify an unbound form, but still some work. I gave up trying to put a complete wrapper on an unbound form
Have you played with ADO.NET? This is a steep learning curve. But yes, using a vb.net datagridview you can control each cell.

Up to yeah, but with that said that is a lot of work for what I did not even notice.
 

Adelina_RO

Member
Local time
Today, 07:16
Joined
Apr 9, 2021
Messages
42
Well I disagree ... but have you tried the standard method of reducing flicker?
Try modifying your Paint event to

Code:
Private Sub Detail_Paint()
If Not Parent!DP Then Exit Sub

Application.Echo False

'the rest of your code here

Application.Echo False

End Sub

Does that help at all?
This was one of the first things i tried :D. Unfortunately (or, by design) the moment the Echo becomes True, access repaints everything on the screen, which in turn makes the annoying flicker.
What do you disagree on? On my machine, the semi-flicker is more obvious with CF than with onpaint. :)
 

Adelina_RO

Member
Local time
Today, 07:16
Joined
Apr 9, 2021
Messages
42
I have almost no flicker on my machine. It is more like a very quick flash. Is that what you are talking about?
If you have to get rid of this, I guess I would do an unbound form.
You have 8 columns. Lets say you have 20 rows then 160 controls not to painful. You can write some code to give them all a consistent naming convention to be used in coding. Then you have your own controls to load 20 records at a time. (next 20, previous 20). Then you color the controls. This is less work then porting it to .net but not trivial. I have some code to simplify an unbound form, but still some work. I gave up trying to put a complete wrapper on an unbound form
Have you played with ADO.NET? This is a steep learning curve. But yes, using a vb.net datagridview you can control each cell.

Up to yeah, but with that said that is a lot of work for what I did not even notice.
Call it as you will, but it's annoying as hell. Flash, flicker, the sensation the whole form is blinking... doesn't look very pro :)))
I have played with .net and i do know about the steep curve... it got me off it a couple of times already, but each time with more knowledge :D - luckily i'm moving to vienna for a few months and, as winter is coming indeed, vienna is rather boring, so i'll have a lot of time on my hands.
About your other ideea, that sounds interesting, but i have a huge db with more than 30 fields to be displayed, so it would be more work than it's worth. But for the future, i bookmarked the page already :)
Thank you :)
 

Users who are viewing this thread

Top Bottom