Bug in IDE?

  • Thread starter Thread starter John
  • Start date Start date
J

John

I found out this by accident when I tried to walk through my code in debug mode:

Here is the step to reproduce:

1. create a project
2. add a form into project
3. add a tab control in project (2 tab pages)
4. put one label (label1) control on tab page 2, set it visible = false
5. put one label (label2) control on form, set it visible = false
6. put one label (label3) control on tab page 1, set it visible = false
7. add a button on form (not inside tab page), set the visible = false

inside the form load code, have the following code:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Me.Button1.Visible = True

If Me.Button1.Visible Then

Button1.Text = "Visible"

Else

Button1.Text = "Invisible"

End If

Me.Label1.Visible = True

If Me.Label1.Visible Then

Me.Label1.Text = "visible"

End If

Me.Label2.Visible = True

If Me.Label2.Visible Then

Me.Label2.Text = "visible"

End If

Me.Label3.Visible = True

If Me.Label3.Visible Then

Me.Label3.Text = "visible"

End If

End Sub

Set break point at first line of code, step line by line,

We have code to set Me.Label1.Visible = True

BUT the next statement will evaluate the the Me.Label1.Visible = False so the Label1.Text will not be set.

Any idea?

This bug/behavior really make code very hard, is there any hotfix for this?

Thanks!
 
I found out this by accident when I tried to walk through my code in debug mode:

Here is the step to reproduce:

1. create a project
2. add a form into project
3. add a tab control in project (2 tab pages)
4. put one label (label1) control on tab page 2, set it visible = false
5. put one label (label2) control on form, set it visible = false
6. put one label (label3) control on tab page 1, set it visible = false
7. add a button on form (not inside tab page), set the visible = false

inside the form load code, have the following code:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Me.Button1.Visible = True

If Me.Button1.Visible Then

Button1.Text = "Visible"

Else

Button1.Text = "Invisible"

End If

Me.Label1.Visible = True

If Me.Label1.Visible Then

Me.Label1.Text = "visible"

End If

Me.Label2.Visible = True

If Me.Label2.Visible Then

Me.Label2.Text = "visible"

End If

Me.Label3.Visible = True

If Me.Label3.Visible Then

Me.Label3.Text = "visible"

End If

End Sub

Set break point at first line of code, step line by line,

We have code to set Me.Label1.Visible = True

BUT the next statement will evaluate the the Me.Label1.Visible = False so the Label1.Text will not be set.

Any idea?

This bug/behavior really make code very hard, is there any hotfix for this?

Thanks!

When you read the value of a control's Visible property, you don't get
back what you set, you get back what you set ANDed with the current
visible state of the control.

If you set Visible to True and the control is not currently visible
(perhaps because the parent control, such as a Tab page, is not
visible), the Visible will return False.

It is unfortunate that the .NET developers chose to do it this way,
but that is how it is and I can not imagine it would ever change.

If you need to remember how you set the Visible property, you will
need to use another property to do that. You could subclass the
controls you need and add a new property to that, or you could put an
object on your form that implements a property on all controls (like
the way ToolTip works). I can't remember right now what that is
called.
 
I found out this by accident when I tried to walk through my code in debug
mode:

Here is the step to reproduce:

1. create a project
2. add a form into project
3. add a tab control in project (2 tab pages)
4. put one label (label1) control on tab page 2, set it visible = false
5. put one label (label2) control on form, set it visible = false
6. put one label (label3) control on tab page 1, set it visible = false
7. add a button on form (not inside tab page), set the visible = false

inside the form load code, have the following code:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Me.Button1.Visible = True
If Me.Button1.Visible Then
Button1.Text = "Visible"
Else
Button1.Text = "Invisible"
End If
Me.Label1.Visible = True
If Me.Label1.Visible Then
Me.Label1.Text = "visible"
End If
Me.Label2.Visible = True
If Me.Label2.Visible Then
Me.Label2.Text = "visible"
End If
Me.Label3.Visible = True
If Me.Label3.Visible Then
Me.Label3.Text = "visible"
End If
End Sub
Set break point at first line of code, step line by line,
We have code to set Me.Label1.Visible = True
BUT the next statement will evaluate the the Me.Label1.Visible = False so
the Label1.Text will not be set.
Any idea?
This bug/behavior really make code very hard, is there any hotfix for this?
Thanks!




You seem to be saying this only occurs in debuging by steping through. It
appears to happen in normal mode too.

I'm not sure why this is the case, but, the labels on whichever tabpage is
not selected are causing the issue. If you set TabControl.SelectedIndex = 0
or 1, when setting the labels to visible, the code will work as you expect.
By the way, this is with express 2008 that I ran this.
 
The Visible property of each control on a form typically returns False during
the Form_Load event. The form is not yet visible, so none of its controls
are vislble. I don't know if it is by design, but it's the way it has always
been.
 
The Visible property of each control on a form typically returns False during
the Form_Load event. The form is not yet visible, so none of its controls
are vislble. I don't know if it is by design, but it's the way it has always
been.
 
That's not true. The visible property is true for all other controls if they
are not in the non-selected tab.
 
John,

A bug is something not known. This is by design since the start of Net.

Herfried has written endless messages about this behaviour.

Please don't call something a bug as you are not sure it is something new.

I as well don't like that design, but some things like this are not changable anymore because it has the chance to break existing code.

Some people can have in their code .Visible is false, as a tabpage is not visible.

Cor

I found out this by accident when I tried to walk through my code in debug mode:

Here is the step to reproduce:

1. create a project
2. add a form into project
3. add a tab control in project (2 tab pages)
4. put one label (label1) control on tab page 2, set it visible = false
5. put one label (label2) control on form, set it visible = false
6. put one label (label3) control on tab page 1, set it visible = false
7. add a button on form (not inside tab page), set the visible = false

inside the form load code, have the following code:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Me.Button1.Visible = True

If Me.Button1.Visible Then

Button1.Text = "Visible"

Else

Button1.Text = "Invisible"

End If

Me.Label1.Visible = True

If Me.Label1.Visible Then

Me.Label1.Text = "visible"

End If

Me.Label2.Visible = True

If Me.Label2.Visible Then

Me.Label2.Text = "visible"

End If

Me.Label3.Visible = True

If Me.Label3.Visible Then

Me.Label3.Text = "visible"

End If

End Sub

Set break point at first line of code, step line by line,

We have code to set Me.Label1.Visible = True

BUT the next statement will evaluate the the Me.Label1.Visible = False so the Label1.Text will not be set.

Any idea?

This bug/behavior really make code very hard, is there any hotfix for this?

Thanks!
 
Hello John,

Thank you for posting this interesting question.

As Cor said, this is by design, not a bug.

Let's see what the document says: The Control.Visible property "Gets or
sets a value indicating whether the control and all its child controls are
displayed."
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.visible
.aspx

So as a child control - Label1 in your case - how do we know if or not it
is visible? Not only the control itself, but also its parents up to the
Form level, are all visible, then this control is *really* visible to the
user. Based on this logic, the implementation of the Visible property (Get)
looks like this (I extracted the following code from
System.Windows.Forms.dll using .NET Reflector, this is not necessarily the
original .NET source code, it might already been optimized, but the logic
shall never change):

If Not Me.GetState(2) Then
Return False
End If
Return ((Me.ParentInternal Is Nothing) OrElse
Me.ParentInternal.GetVisibleCore)

From the code, we can see the logic clearly:
1. If the control itself is NOT visible, return False directly.
2. Otherwise:
2.1 If this is the top level control (no parent), return True.
2.2 If it has parents, get parents' Visible value recursively, until we
reach a parent which is NOT visible - then this control (child) can't be
visible either; or we reached the visible top level parent, so this control
is visible.

Actually, this behavior matches the behavior of the Win32 API function
"IsWindowVisible" (user32.dll), which says: If the specified window, its
parent window, its parent's parent window, and so forth, have the
WS_VISIBLE style, the return value is nonzero. Otherwise, the return value
is zero.
http://msdn.microsoft.com/en-us/library/ms633530.aspx

So maybe we shall have two properties for control visibility: one called
ShallBeVisible, and the other is called IsReallyVisible. The first one is
for your case here, and the latter one is used to get the current visiblity
of the control. However, at this time, we only got half of each, when you
set the Visible property, it is ShallBeVisible, when you get the Visible
property, it is IsReallyVisible.

To me, the workaround to your problem is:
* Change the code logic.
Or
* Have my own control inherits from Label and add my own ShallBeVisible
property.

Please kindly let me know if my explanation addresses your concern.

Regards,

Jie Wang ([email protected], remove 'online.')

Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

Note: MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 2 business days is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions. Issues of this
nature are best handled working with a dedicated Microsoft Support Engineer
by contacting Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Thanks Jie. I understood your explanation completely and I agree 100% that
we need two properties for that.

Here is what I did to work around that:

I created 2 extension methods for control, IsVisible and SetIsVisible. from
the extension methods, I leverage the control.Tag to store the settings.
Another good enhancement for control would be: have a property UserData
with type Dictionary(Of String, Object) so wedo not need to cast it back and
forth as using Tag property :)

Thanks for all.

"Jie Wang [MSFT]" said:
Hello John,

Thank you for posting this interesting question.

As Cor said, this is by design, not a bug.

Let's see what the document says: The Control.Visible property "Gets or
sets a value indicating whether the control and all its child controls are
displayed."
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.visible
aspx

So as a child control - Label1 in your case - how do we know if or not it
is visible? Not only the control itself, but also its parents up to the
Form level, are all visible, then this control is *really* visible to the
user. Based on this logic, the implementation of the Visible property
(Get)
looks like this (I extracted the following code from
System.Windows.Forms.dll using .NET Reflector, this is not necessarily the
original .NET source code, it might already been optimized, but the logic
shall never change):

If Not Me.GetState(2) Then
Return False
End If
Return ((Me.ParentInternal Is Nothing) OrElse
Me.ParentInternal.GetVisibleCore)

From the code, we can see the logic clearly:
1. If the control itself is NOT visible, return False directly.
2. Otherwise:
2.1 If this is the top level control (no parent), return True.
2.2 If it has parents, get parents' Visible value recursively, until we
reach a parent which is NOT visible - then this control (child) can't be
visible either; or we reached the visible top level parent, so this
control
is visible.

Actually, this behavior matches the behavior of the Win32 API function
"IsWindowVisible" (user32.dll), which says: If the specified window, its
parent window, its parent's parent window, and so forth, have the
WS_VISIBLE style, the return value is nonzero. Otherwise, the return value
is zero.
http://msdn.microsoft.com/en-us/library/ms633530.aspx

So maybe we shall have two properties for control visibility: one called
ShallBeVisible, and the other is called IsReallyVisible. The first one is
for your case here, and the latter one is used to get the current
visiblity
of the control. However, at this time, we only got half of each, when you
set the Visible property, it is ShallBeVisible, when you get the Visible
property, it is IsReallyVisible.

To me, the workaround to your problem is:
* Change the code logic.
Or
* Have my own control inherits from Label and add my own ShallBeVisible
property.

Please kindly let me know if my explanation addresses your concern.

Regards,

Jie Wang ([email protected], remove 'online.')

Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

Note: MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 2 business days is acceptable. Please note that each
follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions. Issues of this
nature are best handled working with a dedicated Microsoft Support
Engineer
by contacting Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx
==================================================
This posting is provided "AS IS" with no warranties, and confers no
rights.
 
Hello John,

With regard to the explained behaviour of Visible with regard to controls
and the forms on which they sit.....

This sort of behavior is one of the reasons that you should *generally* avoid
making decisions based on properties of controls.

In this case you should create a Variable (perhaps a boolean ) on which to
base whether a given control should be visible or not.

Then you base other logic, not on the visiblility of the control (which while
not undeterminable, is still tricky to understand), but on the state of your
variable.

This also helps when you later need to change the basis for the decision
in response to user requests/change in business logic.


I wonder if I can explain this better with the following

-------------------------------------------------------------
Public Sub SomeMethod()
Dim ShouldIShowStuff as Boolean = False
Call UpdateControls(ShouldIShowStuff)
'
' Some more code here
'
ShouldIShowStuff = true
Call UpdateControls(ShouldIShowStuff)
End Sub


Public Sub UpdateControls(ShowControls1And3 as Boolean)
Control1.Visible = ShowControls1And3
Control2.Visible = Not Show
Control3.Visible = ShowControls1And3
End Sub
 
Back
Top