Code Says One Thing, Debugger(Watch) Says Another

E

eBob.com

I suppose this has to be my own dumb mistake, but it sure has me mystified.
If I step through the code below using the Debugger and Watch I see one
value, but the code reports, via MsgBox, a different value!

Private Function DeterminePanelUsableWidth(ByRef width As Integer) As
Integer
' determine the width of a panel with a vertical scroll bar
Dim somepanel As New Panel
somepanel.Height = 100
somepanel.AutoScroll = True
somepanel.Width = width
Dim whatever As New TextBox
whatever.Height = somepanel.Height * 2
whatever.Location = New Point(0, 0)
somepanel.Controls.Add(whatever)
Dim ii As Integer = 0
Dim whatever2 As New TextBox
whatever2.Height = somepanel.Height * 2
whatever2.Location = New Point(0, somepanel.Height * 2)
somepanel.Controls.Add(whatever2)
DeterminePanelUsableWidth = somepanel.ClientSize.Width
MsgBox("somepanel.ClientSize.Width is " &
somepanel.ClientSize.Width.ToString & vbCrLf & _
"DeterminePanelUsableWidth is " &
DeterminePanelUsableWidth.ToString)
End Function

For "somepanel.ClientSize.Width" the code sees a value of 479 (as reported
via the MsgBox), but using the Debugger and Watch I see a value of 459 -
which I'm reasonably sure is the right value. 479, incidentally, is the
value of "width" on entry to the DeterminePanelUsableWidth.

(What the function is trying to do is to figure out the usable width in a
panel, i.e. the width of the panel minus the width of the vertical scroll
bar. I know that it's an inelegant implementation of an inelegant
solution.)

Thanks, Bob
 
C

Cor Ligthert[MVP]

Hi,

Probably as you show the messagebox, something is changing in the format on
screen.

You can try that by simple first set the sizes in a variable and then show
the variables.

Cor
 
A

Armin Zingler

eBob.com said:
For "somepanel.ClientSize.Width" the code sees a value of 479 (as
reported via the MsgBox), but using the Debugger and Watch I see a
value of 459

What exactly is the watched expression?
- which I'm reasonably sure is the right value. 479,
incidentally, is the value of "width" on entry to the
DeterminePanelUsableWidth.

(What the function is trying to do is to figure out the usable width
in a panel, i.e. the width of the panel minus the width of the
vertical scroll bar. I know that it's an inelegant implementation of
an inelegant solution.)

What about the other thread dealing with that problem? :)


Armin
 
E

eBob.com

Hi Armin,

Thanks for your interest. Your questions are answered below.

Armin Zingler said:
What exactly is the watched expression?

I tell the Debugger to "Watch" "somepanel" and then scroll the Watch window
so that I can see the ClientSize property of somepanel. In particular I am
keeping an eye on ClientSize.Width.
What about the other thread dealing with that problem? :)

I'm doing what I thought the response to my earlier post recommended; i.e.
using ClientRectangle or ClientSize. Maybe I've misunderstood something but
ClientRectangle and ClientSize seem to provide the CURRENT client area. I
want the client area after there's a vertical scroll bar. This was the only
solution I could think of. I.E. jam enough stuff in a panel so that there
will be a vertical scroll bar and then check the ClientSize. If there's a
better solution I don't see it.

Thanks again for your interest and help.
 
A

Armin Zingler

eBob.com said:
I tell the Debugger to "Watch" "somepanel" and then scroll the Watch
window so that I can see the ClientSize property of somepanel. In
particular I am keeping an eye on ClientSize.Width.

Passing in 479, my watch window shows 461 for somepanel.clientsize.width and
the Messagebox shows the same value. => Can't repro the problem.

I'm doing what I thought the response to my earlier post recommended;
i.e. using ClientRectangle or ClientSize. Maybe I've misunderstood
something but ClientRectangle and ClientSize seem to provide the
CURRENT client area.
Right.

I want the client area after there's a vertical
scroll bar. This was the only solution I could think of. I.E. jam
enough stuff in a panel so that there will be a vertical scroll bar
and then check the ClientSize. If there's a better solution I don't
see it.

Maybe I misunderstood the purpose of your function, but it looks as if it is
there to determine the clientsize _if_ there is a scrollbar _in advance_. I
don't know why you just don't use the clientsize value at any time you need
it. It's always correct if there's a scrollbar or not.

If you really need to know the size of the scrollbar - using the clientsize
was an attempt to do without - you can also have a look at the
SystemInformation class (System.Windows.Forms.SystemInformation) which has a
shared VerticalScrollBarWidth property.

Armin
 
C

Cor Ligthert[MVP]

Hi Bob,

That I have as well often, when I go to the imitate window, there are
changes on the screen, all was it simple that the focus comes on that.

This reflects direct in the results you see about anything on the screen.

Cor
 
E

eBob.com

Hi Armin,

Thanks for such a prompt response. Further comments below ...

Armin Zingler said:
Passing in 479, my watch window shows 461 for somepanel.clientsize.width
and
the Messagebox shows the same value. => Can't repro the problem.

Hmmmm ... maybe it depends on software levels. I've been running on a Vista
x64 box with VBE 2008 and .Net 3.5 SP1. My other machines have the same
level of VBE and .Net but they are XP. I'll try them.
Maybe I misunderstood the purpose of your function, but it looks as if it
is
there to determine the clientsize _if_ there is a scrollbar _in advance_.
I
don't know why you just don't use the clientsize value at any time you
need
it. It's always correct if there's a scrollbar or not.
Well ... I want to use as much of the width as possible when I put a textbox
into the panel. But I don't want anything the user can see in that textbox
to then be hidden behind the vertical scroll bar if/when the panel needs
one. I suppose the automatic horizontal scroll bar would take care of that,
but I'd like to avoid a horizontal scroll because my vertical pixels are
expensive - i.e. my screen layout is tight on vertical space. If it were
possible with a panel I'd turn on the vertical scroll bar before I added any
controls to it. But that's not possible. Changing the width of the
textboxes if/when the vertical scroll appears might be a solution but I'd
rather create them at a width which won't require change.
If you really need to know the size of the scrollbar - using the
clientsize was an attempt to do without - you can also have a look at the
SystemInformation class (System.Windows.Forms.SystemInformation) which has
a shared VerticalScrollBarWidth property.

That sure sounds like what I was after. But I have discovered that .NET has
two kinds of vertical scroll bars - the kind it creates for you (i.e. as
part of a control) and the kind you can create yourself (i.e. a "standalone"
scroll bar). They look different but I forget now if the width is
different. I've posted on that before but cannot not find that post now.

Thanks again for your helpful, as always, help. Bob
 
A

Armin Zingler

eBob.com said:
Well ... I want to use as much of the width as possible when I put a
textbox into the panel. But I don't want anything the user can see
in that textbox to then be hidden behind the vertical scroll bar
if/when the panel needs one. I suppose the automatic horizontal
scroll bar would take care of that, but I'd like to avoid a
horizontal scroll because my vertical pixels are expensive - i.e. my
screen layout is tight on vertical space. If it were possible with a
panel I'd turn on the vertical scroll bar before I added any controls
to it. But that's not possible. Changing the width of the textboxes
if/when the vertical scroll appears might be a solution but I'd
rather create them at a width which won't require change.

Considered docking the textboxes (Dock=Top)?


Armin
 
E

eBob.com

The problem continues to mystify me. The code appended below is a bit
cleaner than what I posted earlier but exhibits the same error, i.e. the
value of Panel.ClientSize.Width does not appear to change after a vertical
scroll bar has been added to the control. The addition of the scroll bar
happens automatically, or should, because I use AutoScroll = True and put
more stuff in the Panel than its visible area can accomodate.

I've learned thru further experimentation that the code works correctly if I
1) put a breakpoint in the code AND 2) have a Watch on "somepanel" with the
properties expanded. It's not good enough to just have a Watch on
"somepanel", I also have to have clicked on the + sign in front of
"somepanel" so that all of the properties are displayed.

Most of my experiments I've done on a Vista x64 system. In the few
experiments I've done on an XP box I get the same result. On the Vista x64
system I've tried three different levels of the Framework and get the same
result with all three levels.

I've also tried turning off optimization and that's made no difference.

The good news is than when, by using the debugger tricks described above, I
see the ClientSize.Width change, it changes by 17, which is indeed the value
of System.Windows.Forms.SystemInformation.VerticalScrollBarWidth. Using
that value is clearly the right and most simple way to insure that my
TextBoxes don't stray into the area of the panel which might eventually be
used by the vertical scroll bar and I never would have written the code I
posted if I had been aware of it. (And thank you again Armin for making me
aware of it!)

So, much as I'd like to get to the bottom of this, I can't think of any
futher experiments and I guess I'll be moving on.

Bob


Public Class Form1
Dim somepanel As New Panel
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

' determine the width of a panel with a vertical scroll bar

Dim DeterminePanelUsableWidth As Integer
Dim stoped_at_index As Integer

Const panel_width As Integer = 275

somepanel.Height = 100
somepanel.AutoScroll = True
somepanel.Width = panel_width

Dim someboxes() As TextBox
Dim someboxes_index As Integer = 0
For someboxes_index = 0 To 999
stoped_at_index = someboxes_index
ReDim Preserve someboxes(someboxes_index)
someboxes(someboxes_index) = New TextBox
With someboxes(someboxes_index)
.Width = 234
If someboxes_index > 0 Then
.Location = New Point(0, _
someboxes_index * (someboxes(0).Height + 1))
End If
somepanel.Controls.Add(someboxes(someboxes_index))
If panel_width > somepanel.ClientSize.Width Then Exit For
End With
Next


DeterminePanelUsableWidth = somepanel.ClientSize.Width

MsgBox("somepanel.ClientSize.Width is " &
somepanel.ClientSize.Width.ToString & vbCrLf & _
"DeterminePanelUsableWidth is " & DeterminePanelUsableWidth.ToString
& vbCrLf & _
"stopped at index " & stoped_at_index.ToString)

Me.Controls.Add(somepanel)

End Sub
End Class
 

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