我编写了一个Web用户控件,我希望能够将其放入aspx页面或其他Web用户控件的标记中。
我需要我的用户控件才能轻松高效地解决其内部的另一个用户控件或aspx页面。我最初的想法是通过对Parent属性的检查递归地执行 - 继续查找嵌套层次结构,直到我找到Web表单或用户控件 - 但我不确定这是解决此问题的最佳方法。
你能建议一个更简单的方法吗?感谢。
答案 0 :(得分:3)
递归检查Parent
的类型,直到Parent.GetType()
为typeof(UserControl)
或type(Page)
private bool IsAncestorTypeOf(Control c, params Type[] typesToCheck)
{
var parent = c.Parent;
if (parent == null) return false;
if (typesToCheck.Contains(parent.GetType())) return true;
return IsAncestorTypeOf(parent, typesToCheck);
}
或者没有递归
private bool IsAncestorTypeOf(Control c, params Type[] typesToCheck)
{
var parent = c.Parent;
while (true)
{
if (parent == null) return false;
if (typesToCheck.Contains(parent.GetType())) return true;
parent = parent.Parent;
}
}
称之为
var isAncestorPageOrUserControl = IsAncestorTypeOf(this, typeof(Page), typeof(UserControl));
或
var isAncestorPage = IsAncestorTypeOf(this, typeof(Page));
var isAncestorUserControl = IsAncestorTypeOf(this, typeof(UserControl));
答案 1 :(得分:1)
通常,组件应该不知道它们的任意容器,尽管容器必须知道它们的组件(除非它是一个强大的依赖情况,如列表项总是在列表类型中,你可以建立一个强大的双向关系)。然而,听起来你正在进入一般的环境。您可能会发现许多情况需要代码才能执行此操作并意外地错过其他情况。
通过让用户控制意识到周围环境和更大的世界,您可能引入依赖,这使得您的控件不再可重用且难以维护。
如果控件需要的内容不在其中,您可以强制开发人员在用户控件的属性上提供对所需内容的引用,从而转向合成。例如,这就是ASP.NET中的验证控件执行此操作的方式,以引用外部控件以通过id进行验证。
当然,我指定的仅在某些时候是实用的。是否有一个特定的原因或边缘情况,为什么您需要让您的用户控件环顾四周,或者您是否可以向开发人员提供有关应该在何处使用控件的说明?
答案 2 :(得分:1)
这应该有效:
C#
bool inPage = (this.NamingContainer == this.Page);
VB.NET
Dim inPage as Boolean = Me.NamingContainer is Me.Page
编辑:它似乎并不像我希望的那么简单。如果用户控件在GridViewRow之类的控件中抵制,则它的NamingControl将是Row而不是Page。
考虑到这一点:
C#
public static bool isControlInPageOruserControl(Control uc)
{
bool inPage = uc.NamingContainer is Page;
if (inPage) {
return true;
} else if (uc.NamingContainer is UserControl) {
return false;
} else {
return isControlInPageOruserControl(uc.NamingContainer);
}
}
VB.NET:
Public Shared Function isControlInPageOruserControl(ByVal uc As Control) As Boolean
Dim inPage As Boolean = TypeOf uc.NamingContainer Is Page
If inPage Then
Return True
ElseIf TypeOf uc.NamingContainer Is UserControl Then
Return False
Else
Return isControlInPageOruserControl(uc.NamingContainer)
End If
End Function