控件的Get of Visible属性以递归方式查找树以指示是否将呈现控件。
我需要一种方法来查看控件的“本地”可见值是什么,而不管其父控件的设置是什么。即它本身是设置为真还是假。
我已经看到了这个问题How to get the “real” value of the Visible property?,它使用Reflection来获取本地状态,但是,我无法让它适用于WebControls。这也是获取价值的一种相当肮脏的方法。
我提出了以下扩展方法。它的工作原理是从父节点中删除控件,检查属性,然后将控件放回到找到它的位置。
public static bool LocalVisible(this Control control)
{
//Get a reference to the parent
Control parent = control.Parent;
//Find where in the parent the control is.
int index = parent.Controls.IndexOf(control);
//Remove the control from the parent.
parent.Controls.Remove(control);
//Store the visible state of the control now it has no parent.
bool visible = control.Visible;
//Add the control back where it was in the parent.
parent.Controls.AddAt(index, control);
//Return the stored visible value.
return visible;
}
这是一种可以接受的方式吗?它工作正常,我没有遇到任何性能问题。它看起来非常脏,我毫不怀疑可能会出现失败的情况(例如,实际渲染时)。
如果有人对这个解决方案有任何想法,或者更好的方法是找到价值,那就更好了。
答案 0 :(得分:3)
经过深入挖掘后,我创建了以下扩展方法,该方法使用反射来检索继承自Visible
的类的System.Web.UI.Control
标志的值:
public static bool LocalVisible(this Control control)
{
var flags = typeof (Control)
.GetField("flags", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(control);
return ! (bool) flags.GetType()
.GetProperty("Item", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(flags, new object[] {0x10});
}
它使用反射来查找flags
对象中的私有字段Control
。此字段使用内部类型声明,因此需要更多反射来调用其索引器属性的getter。
扩展方法已在以下标记上进行了测试:
<asp:Panel Visible="false" runat="server">
<asp:Literal ID="litA" runat="server" />
<asp:Literal ID="litB" Visible="true" runat="server" />
<asp:Literal ID="litC" Visible="false" runat="server" />
</asp:Panel>
<asp:Literal ID="litD" runat="server" />
<asp:Literal ID="litE" Visible="true" runat="server" />
<asp:Literal ID="litF" Visible="false" runat="server" />
测试结果:
litA.LocalVisible() == true
litB.LocalVisible() == true
litC.LocalVisible() == false
litD.LocalVisible() == true
litE.LocalVisible() == true
litF.LocalVisible() == false
答案 1 :(得分:0)
您可以使用Property公开控件的可见性。这可以解决您的问题。
如果我错了,请纠正我。
答案 2 :(得分:0)
如果有人试图让JørnSchou-Rode的代码在VB.NET中运行,那么以下代码对我有用。当我在VB中简单地翻译他的代码时,我得到了一个“模糊匹配”异常,因为有3种风格的标志“Item”属性。
<Extension()>
Public Function GetLocalVisible(ctl As Control) As Boolean
Dim flags As Object = GetType(Control).GetField("flags", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(ctl)
Dim infos As PropertyInfo() = flags.GetType().GetProperties(BindingFlags.Instance Or BindingFlags.NonPublic)
For Each info As PropertyInfo In infos
If info.Name = "Item" AndAlso info.PropertyType.Name = "Boolean" Then
Return Not CBool(info.GetValue(flags, New Object() {&H10}))
End If
Next
Return ctl.Visible
End Function