嵌套的ASCX控件'页面级别无法访问的属性

时间:2015-02-19 09:46:21

标签: asp.net webforms user-controls asp.net-4.5

注意,在标记为重复之前 - 之前曾询问过similar个问题,但所有参考特定第三方库都提供了匹配的解决方案。这个问题仅涉及原生的ASP.Net框架,我正在寻找为什么除了最佳解决方案之外还会出现此行为的解释。

我有一个像这样的页面结构:

enter image description here

在ControlA中,我将文本框公开为Public Property,以便我可以在页面级别访问它。因此,在页面级别,这非常有效:

Trace.Warn(ControlA.TextBoxA.Text) ' prints "Control A Text Box"

但是,以相同的方式将ControlB的文本框公开为公共属性不允许它在页面级别可用。这个代码在页面级......

Trace.Warn(ControlA.NestedControlB.TextBoxB.Text)

...因此错误而失败:

  

BC30652:汇编需要参考' App_Web_3jwc5ppn

在ControlB中放置的任何需要在页面级别可访问的方法也是如此。 单击"添加参考"链接没有任何结果,而且,程序集标题会在项目重建的每个时间内更改。

一种解决方案,但对于复杂的控制来说它是最好的吗?

我可以通过将ControlB文本框声明为ControlA中的属性来冒泡属性,如下所示:

Public ReadOnly Property NestedControlBTextBox As TextBox
    Get
        Return ControlB.TextBoxB()
    End Get
End Property

这允许嵌套文本框在页面级别可访问:

Trace.Warn(ControlA.NestedControlBTextBox.Text) ' prints "Control B Text Box"

但这是最好/最正确的方法吗?将每个属性和/或事件冒充N级层次结构似乎是一项非常繁重的工作。显然,我真正的ASCX控件比这更复杂。

我有enclosed the solution,以防有人想要说明更好的方法。

1 个答案:

答案 0 :(得分:0)

您的错误:"为什么会出现这种情况" ...

要使用当前语法访问属性,您需要在父页面上添加缺少的嵌套控件引用。您只在父页面上注册ControlA,而不是ControlB。因此,尝试以您的方式访问嵌套控件属性不起作用,因为它可以访问ControlA,但无法访问ControlA中存在的所有引用(即ControlB的属性)。除非您在父级上注册嵌套控件,否则您当前的语法将不起作用。这看起来并不理想,也不会非常易读。

您的解决方案:这是最好的解决方案吗?

根据微软的THIS文章,您应该像现在这样解决问题。添加属性和方法,将所需的值从嵌套控件返回到父控件(ControlA)。这很烦人,因为你的控件变得更复杂,或者有多层嵌套,会很痛苦。

我的解决方案:

也许我是反叛者,但我不想因为我的父母页面而改变控制权。这么说。每次我需要新值时,我都不想修改控件以访问父页面的嵌套控件值。

要获得嵌套控件的控件值(即嵌套控件上的TextBox),我只是这样做:

Dim myTextBoxB = CType(ControlA.FindControl("ControlB").FindControl("txt_controlB"), TextBox)
Trace.Warn(myTextBoxB.Text)

为了更深层次,你可以这样做:

Dim myTextBoxC = CType(ControlA.FindControl("ControlB").FindControl("ControlC").FindControl("txt_controlC"), TextBox)
Trace.Warn(myTextBoxC.Text)

用户控制背后的整个理念是模块化和简化。在寻找最佳实践的同时,请务必记住,在嵌套兔子洞中越深入,在尝试访问嵌套控件的值时,应用程序的耦合性就会越紧密......