如何获取 Asp.Net 中 Visible 属性的设置/实际值

发布于 2024-08-16 16:35:35 字数 1153 浏览 7 评论 0原文

控件的 Visible 属性的 Get 会递归地查找树以指示该控件是否将被呈现。

我需要一种方法来查看控件的“本地”可见值,无论其父控件设置为何。即它本身是否被设置为 true 或 false。

我看过这个问题,如何获得“真实值” ” Visible 属性的值? 它使用反射来获取本地状态,但是,我无法在 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;
    }

这是一种可以接受的方式吗?它运行良好,我没有遇到任何性能问题。它看起来非常脏,我毫不怀疑在某些情况下它可能会失败(例如,在实际渲染时)。

如果有人对此解决方案有任何想法,或者更好地找到价值的更好方法,那就太好了。

The Get of the Visible property of a control recursively looks up the tree to indicate if the control will be rendered or not.

I need a way to see what the "local" visible value of a control is regardless of what its parent controls are set to. i.e. Whether it itself was set to true or false.

I have seen this question, How to get the “real” value of the Visible property? which uses Reflection to obtain the local state, however, I have not been able to get this working for WebControls. It's also a rather dirty method of getting the value.

I have come up with the following extension method. It works by removing the control from its parent, checking the property, then putting the control back where it found it.

    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;
    }

Is this an acceptable way of doing this? It works fine and I haven't come across any performance issues. It just seems extremely dirty and I have no doubt there could be instances in which it might fail (for example, when actually rendering).

If anyone has any thoughts on this solution or better still a nicer way of finding the value then that would be great.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

水溶 2024-08-23 16:35:35

经过一番研究后,我生成了以下扩展方法,该方法使用反射来检索继承自 System.Web.UI.Control 的类的 Visible 标志的值:

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});
}

它使用反射来查找 Control 对象中的私有字段 flags。该字段是使用内部类型声明的,因此需要更多反射来调用其索引器属性的 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

After digging around a bit, I have produced the following extension method that uses reflection to retrieve the value of the Visible flag for classes inheriting from 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});
}

It uses reflection to find the private field flags within the Control object. This field is declared with an internal type, so more reflection is needed to invoke the getter of its indexer property.

The extension method has been tested on the following markup:

<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" />

Test results:

litA.LocalVisible() == true
litB.LocalVisible() == true
litC.LocalVisible() == false
litD.LocalVisible() == true
litE.LocalVisible() == true
litF.LocalVisible() == false
你是年少的欢喜 2024-08-23 16:35:35

您可以使用属性公开控件的可见性。这可以解决你的问题。

如果我错了,请纠正我。

You can expose the visiblility of controls using Property. This could solve your problem.

Please correct me if I am wrong.

萌无敌 2024-08-23 16:35:35

如果有人试图让 Jørn Schou-Rode 的代码在 VB.NET 中运行,这里是适合我的代码。当我简单地用 VB 翻译他的代码时,我得到一个“发现不明确的匹配”异常,因为标志“Item”属性有 3 种风格。

<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

In case someone tries to get Jørn Schou-Rode's code working in VB.NET, here is the code that works for me. When I simply translate his code in VB, I get an "Ambiguous match found" exception, because there are 3 flavors of the flags "Item" property.

<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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文