I have a custom UserControl whose .Visible property I need to set to True or False. However, if the UserControl's first child control is a Panel and its ID is cMain, I want it to set the Panel's .Visible property instead of the UserControl's. Here's my code:
Here's the custom class I use:
Public MustInherit Class MyControl : Inherits UserControl
Public Overrides Property Visible As Boolean
Get
Return GetVisible()
End Get
Set(value As Boolean)
SetVisible(value)
End Set
End Property
Function GetVisible() As Boolean
Dim c As Control = GetMain()
If TypeOf c Is Panel Then
Return c.Visible
Else
Return MyBase.Visible
End If
End Function
Sub SetVisible(Value As Boolean)
Dim c As Control = GetMain()
If TypeOf c Is Panel Then
c.Visible = Value
Else
MyBase.Visible = Value
End If
End Sub
Function GetMain() As Control
Dim c As Control = If(Controls.Count = 0, Nothing, Controls(0))
If Not (TypeOf c Is Panel AndAlso c.ID = "cMain") Then c = Me
Return c
End Function
End Class
Here's the actual UserControl itself:
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="TestControl.ascx.vb" Inherits="JsonJqueryDevex.TestControl1" %>
<asp:Panel ID="cMain" runat="server">
inside
</asp:Panel>
outside
UserControl's codebehind:
Public Class TestControl1
Inherits MyControl
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
End Class
Here's the markup to implement it into the host page:
<uc:TestControl ID="ucTest" Visible="true" runat="server"></uc:TestControl>
Notice that I overrode .Visible within my base clase. I did this so that I could call MyBase if the control being referenced is the UserControl itself. Otherwise, I assume it's the Panel control. When I load the page, I get System.StackOverflowException
. What's funny is that I don't get this when I have the custom control's Visible property set to false
in the markup.
The stack trace shows that it's getting caught in .Visible's get accessor when it calls Return GetVisible()
. If it's a Panel, it will execute Return c.Visible
. However, as soon as I reference .Visible when c is a Panel, it breaks back into MyControl's .Visible get accessor. I don't know how this is possible since I am only overriding my custom control's Visible property, but it's acting as if I am overriding the Panel's .Visible property. What is going on here?
Your problem is with the behavior of Control.Visible
.
Your program is working when the value is false
because it simply returns false
at the point that it is checked. However, a control will not return true
for .Visible
unless both the control is visible and the parent is visible.
What's happening in your case is that, when true
, the parent is checking a child control for its .Visible
value, and any child controls will check its parent (your user control) in addition to its own .Visible
value. This is where your infinite recursion loop occurs, causing the stack overflow.