【问题标题】:ASP.NEt WebForms UserControl: Why is overriding .Visible causing a System.StackOverflowException?ASP.NEt WebForms UserControl:为什么覆盖 .Visible 会导致 System.StackOverflowException?
【发布时间】: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


【解决方案1】:

您的问题在于Control.Visible 的行为。

当值为false 时,您的程序正在运行,因为它只是在检查时返回false。但是,对于.Visible,控件不会返回true除非该控件可见并且父级可见

在您的情况下发生的情况是,当true 时,父级正在检查子控件的.Visible 值,并且任何子控件除了自己的@987654329 之外,还将检查其父级(您的用户控件) @ 价值。这是你的无限递归循环发生的地方,导致堆栈溢出。

【讨论】:

  • 有趣!我使用'new'关键字而不是'override'关键字,它可以正常工作。
猜你喜欢
  • 2018-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-29
  • 1970-01-01
  • 2021-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多