【发布时间】:2012-09-18 16:38:05
【问题描述】:
我有一个自定义 UserControl,我需要将其 .Visible 属性设置为 True 或 False。但是,如果 UserControl 的第一个子控件是 Panel 并且它的 ID 是 cMain,我希望它设置 Panel 的 .Visible 属性而不是 UserControl 的。这是我的代码:
这是我使用的自定义类:
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
这是实际的 UserControl 本身:
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="TestControl.ascx.vb" Inherits="JsonJqueryDevex.TestControl1" %>
<asp:Panel ID="cMain" runat="server">
inside
</asp:Panel>
outside
UserControl 的代码隐藏:
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
这是在主机页面中实现它的标记:
<uc:TestControl ID="ucTest" Visible="true" runat="server"></uc:TestControl>
请注意,我在基类中覆盖了 .Visible。我这样做是为了如果被引用的控件是 UserControl 本身,我可以调用 MyBase。否则,我认为它是面板控件。当我加载页面时,我得到System.StackOverflowException。有趣的是,当我在标记中将自定义控件的 Visible 属性设置为 false 时,我没有得到这个。
堆栈跟踪显示它在调用Return GetVisible() 时被.Visible 的get 访问器捕获。如果是 Panel,它将执行Return c.Visible。但是,一旦我在 c 是 Panel 时引用 .Visible ,它就会重新进入 MyControl 的 .Visible 获取访问器。我不知道这是怎么可能的,因为我只是覆盖了我的自定义控件的 Visible 属性,但它就像我覆盖了面板的 .Visible 属性一样。这是怎么回事?
【问题讨论】:
-
你设置断点了吗?
Controls(0)在您的GetMain()方法中的值是多少?标记中的静态文本(甚至是空格)通常会在Controls集合中以LiteralControl结尾。如果这是您的情况,那么您的条件将始终返回Me,因此是无限循环和StackOverflowException的原因 -
不,肯定是小组。正如您在代码中看到的,我强制它检查类型和 ID。
标签: asp.net user-controls webforms overriding stack-overflow