Please help, more scrollbar questions. CODE INCLUDED.

C

Colin McGuire

I apologize for posting yet another scrollbar question. Here is my
code. All I want is for a diagonal line to appear from coordinates
(0,0) to (width,height) in a usercontrol regardless of whether the
user autoscrolls the usercontrol (other things that are on the
usercontrol I want to scroll, but haven't included any here).

Here are the steps to reproduce my problem.

1. Launch Visual Studio and create a new Windows
application with "Form1".
2. Paste the following in (remember to include
your "Windows Form Designer generated code).
3. Run - instructions are in the program that runs.

I am using "Microsoft Development Environment 2003, Version 7.1.3088".
I am using "Microsoft .NET Framework 1.1, Version 1.1.4322"

Thank you for your patience with me.
Colin



Public Class Form1
Inherits System.Windows.Forms.Form

'======================
' Windows Form Designer generated code
' (INCLUDE HERE FOR FORM1 FROM YOUR IDE, NOT POSTED HERE)
'======================

Public Class UserControl1
Inherits System.Windows.Forms.UserControl
Protected Overrides Sub OnPaint(ByVal p As PaintEventArgs)
MyBase.OnPaint(p)
p.Graphics.DrawLine(New Pen(Color.Black), _
clientRectangle.Width, _
ClientRectangle.Height, _
0, 0)
End Sub

Private Sub UserControl1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
Me.BackColor = Color.Yellow
End Sub
End Class


Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim uc As New UserControl1
uc.Location = New Point(0, 0)
uc.Size = New System.Drawing.Size(New Point(100, 100))
uc.BackColor = Color.Yellow
uc.AutoScroll = True
uc.AutoScrollMinSize = New Size(New Point(200, 300))
uc.Visible = True
Me.Controls.Add(uc)
Size = New Size(New Point(300, 300))

Dim lb As New Label
lb.Location = New Point(0, 150)
lb.Size = New Size(290, 80)
lb.Text = "1.Move the scrollbars,the diagonal line isn't" + _
" drawn from(0,0) to (width,height). 2.Minimize" + _
" this form. 3. Restore the form size,now the " + _
"line does go from (0,0) to (width,height). " + _
"Why, why isn't the diagonal line and " + _
"control background cleared as you scroll?"
Me.Controls.Add(lb)
End Sub
End Class
 
C

Colin McGuire

You're not going to make me thank you again I hope :)

Here is some more elaboration of my problem.

What I see is:

1. When I move the vertical scrollbar by clicking "in"
the scrollbar (ie between the up arrow and down arrow),
the diagonal line is drawn properly (diagram below).

+----------+
|\ |
| \ |
| \ |
| \ |
| \ |
| \ |
| \ |
| \ |
| \ |
| \|
+----------+

2. When I click the "down arrow" button on the vertical
scrollbar, the diagonal scrolls, but I can see a tiny
bit of the new diagonal showing up - sort of looks like

+---\-------+
| \ |
| \ |
| \ |
| \ |
| \ |
| \ |
| \|
| |
| |
| \|
+-----------+

3. When I add a Debug.WriteLine("OnPaint") inside
the OnPaint method, both clicking "in" the scrollbar
and clicking the up or down arrow of the scrollbar
appear produce "OnPaint" in the IDE debug window.

4. When I minimise this (corrupted window, step 2), then
maximize it again, then it redraws properly with
the diagonal from (0,0) to (width,height) as shown
in Step 1.

BTW: I forgot to paste in the

p.Graphics.Clear(BackColor)

in my original post before the
p.Graphics.DrawLine .... but
it doesn't make any difference if I do.

Thank you
Colin
 
O

One Handed Man

You need to repaint on VScroll. Your user control inherits from Scrollable
class and this event is protected so as you have inherited this you should
be able to add a handler and force the control to repaint.
 
C

Colin McGuire

OHM, I am sorry - I have seen this mentioned before and have never
understood it. I know I'm close and the cigar eludes me. Any chance of
coaching me on just a little further?


Here is what I think what you mean from your latest post, and as I have
implemented it is wrong because I get an a box showing up in my IDE saying
"'VScroll' is not an event of WindowsApplication15.Form1.UserControl1'".

What I did to my original code was

Step 1: Added the following to UserControl1_Load

AddHandler VScroll, AddressOf capturedVScroll

Step 2: Added the following to the code in UserControl1

Private Sub capturedVScroll(ByVal sender As Object, _
ByVal e As System.EventArgs)
Debug.WriteLine("capturedVScroll")
End Sub


My final code therefore looks like this, but just one more tweak is
necessary before I can get it to compile and work.

Colin

Public Class Form1
Inherits System.Windows.Forms.Form

'======================
' Windows Form Designer generated code
' (INCLUDE HERE FOR FORM1 FROM YOUR IDE, NOT POSTED HERE)
'======================

Public Class UserControl1
Inherits System.Windows.Forms.UserControl
Protected Overrides Sub OnPaint(ByVal p As PaintEventArgs)
MyBase.OnPaint(p)
p.Graphics.Clear(BackColor)
p.Graphics.DrawLine(New Pen(Color.Black), _
clientRectangle.Width, _
ClientRectangle.Height, _
0, 0)
End Sub

Private Sub UserControl1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
Me.BackColor = Color.Yellow
AddHandler VScroll, AddressOf capturedVScroll 'ERROR HERE
End Sub

Private Sub capturedVScroll(ByVal sender As Object, _
ByVal e As System.EventArgs)
Debug.WriteLine("capturedVScroll")
End Sub

End Class


Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim uc As New UserControl1
uc.Location = New Point(0, 0)
uc.Size = New System.Drawing.Size(New Point(100, 100))
uc.BackColor = Color.Yellow
uc.AutoScroll = True
uc.AutoScrollMinSize = New Size(New Point(200, 300))
uc.Visible = True
Me.Controls.Add(uc)
Size = New Size(New Point(300, 300))

Dim lb As New Label
lb.Location = New Point(0, 150)
lb.Size = New Size(290, 80)
lb.Text = "1.Move the scrollbars,the diagonal line isn't" + _
" drawn from(0,0) to (width,height). 2.Minimize" + _
" this form. 3. Restore the form size,now the " + _
"line does go from (0,0) to (width,height). " + _
"Why, why isn't the diagonal line and " + _
"control background cleared as you scroll?"
Me.Controls.Add(lb)
End Sub
End Class
 
O

One Handed Man

Actually, I was wrong. It is not an event. However, logic tells us that an
event has taken place because otherwise it could not have scrolled.

I suggest you post this exact question as a new thread and this will get you
your answer. I dont know it at present.
 
H

hexathioorthooxalate

Paste the following code into UserControl1
Hexathioorthooxalate


'Putting a Debug.WriteLine(m.ToString) in the subroutine below
'shows that the order that messages are received/processed is
'WM_PAINT and then WM_XSCROLL. The usercontrol appears to be
'being painted first, and then scrolled, and this is why you
'are not seeing the diagonal. This code will ensure that
'after a scroll, a repaint (through Invalidate()) will
'occur - messy and probably overkill but I cannot currently
'see another way around your dilemma.

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
MyBase.WndProc(m)
'0x115=WM_VSCROLL, 0x114=WM_HSCROLL
If m.Msg = &H115 Or m.Msg = &H114 Then Invalidate()
End Sub
 
O

One Handed Man

This is not a workable solution. The reason being that once you invalidate ,
it causes a paint event, which causes . . . . Flashing forms, lines etc

Recursive.

OHM
 
B

Brian

Colin, put this in your New()

Me.SetStyle(ControlStyles.DoubleBuffer, True)
Me.SetStyle(ControlStyles.ResizeRedraw, True)
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
Me.SetStyle(ControlStyles.UserPaint, True)



Tihis will force the control to repaint the entire surface. What is
happening is that your control is painting only the uncover part and not the
whole window.
 
H

hexathioorthooxalate

Flickering: reverse the methods (modified below)
Recursive: no.


Protected Overrides Sub WndProc(ByRef m As _
System.Windows.Forms.Message)

'0x115=WM_VSCROLL, 0x114=WM_HSCROLL
If m.Msg = &H115 Or m.Msg = &H114 Then Invalidate()
MyBase.WndProc(m)
End Sub
 
H

hexathioorthooxalate

Yes, a much better solution.


Brian said:
Colin, put this in your New()

Me.SetStyle(ControlStyles.DoubleBuffer, True)
Me.SetStyle(ControlStyles.ResizeRedraw, True)
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
Me.SetStyle(ControlStyles.UserPaint, True)



Tihis will force the control to repaint the entire surface. What is
happening is that your control is painting only the uncover part and not the
whole window.
 
O

One Handed Man

Nope sorry. The line flickes all the time because the paint events are
continually firing.

OHM
 
O

One Handed Man

Sorry, I forgot to take out a refresh in the paint event.


Yes, it works a treat. Thanks for your help


Regards OHM
 
H

hexathioorthooxalate

Are you sure? Not for me? You might be right but I can't see it. Why would
continually refresh?
The WndProc only causes a repaint when via WM_VSCROLL and WM_HSCROLL
messages are detected, which isn't every time. I don't see how it can be
continually firing.
 
H

hexathioorthooxalate

We posted at the same time, just read what you had written.
Glad to be of help - Brian's solution is nicer though.
Hexathioorthooxalate.
 
O

One Handed Man

hexathioorthooxalate solution DOES not work for me, unfortunatley, Brian's
didnt



OHM
 
O

One Handed Man

Just out of curiosity, was this requirement to demonstrate to the UI user
that this control was disabled in some way ?
 
C

Colin McGuire

The diagonal was just a line to use for testing purposes. Really what I am
doing is drawing a ruler at the top of the usercontrol, everything in the
usercontrol should appear to scroll except the ruler at the top which should
appear to stay in the same position.

On my system
hexathioorthooxalate's solution works
Brians does not, when I add

Public Sub New()
Me.SetStyle(ControlStyles.DoubleBuffer, True)
Me.SetStyle(ControlStyles.ResizeRedraw, True)
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
Me.SetStyle(ControlStyles.UserPaint, True)
End Sub

it behaves the same and doesn't draw the diagonal correctly.


Never-the-less, it is working now and thank you OHM, hexathioorthooxalate,
and Brian.

Colin
 
B

Brian

Oops, I should have mentioned that the code I gave you is for when the
control is being resized. It's basically used to prevent flickering
of the control. I don't believe it has any effect during runtime
(except during the controls resize event). That's why you said it didn't
work, it's because it didn't. Using Invalidate() will erase the entire form.
 
O

One Handed Man

Top marks to hexathioorthooxalate's for this. This is something i've learnt
and wont forget.

BTW hex, what does you name mean exactly. "hex =HEX 'athioorthoo'
xalate's = TRANSLATES"
Have you run some algorithm against your name which is in the centre ?

OHM
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top