Как получить установленное / реальное значение свойства Visible в Asp.Net - PullRequest
4 голосов
/ 05 января 2010

Свойство Get of Visible элемента управления рекурсивно просматривает дерево, чтобы указать, будет ли отображаться элемент управления или нет.

Мне нужен способ узнать, каково «локальное» видимое значение элемента управления независимо от того, на что установлены его родительские элементы управления. то есть было ли для него установлено значение true или false.

Я видел этот вопрос, Как получить «реальное» значение свойства Visible? , которое использует 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;
    }

Это приемлемый способ сделать это? Работает нормально, проблем с производительностью не возникало. Это просто кажется очень грязным, и я не сомневаюсь, что могут быть случаи, когда он может потерпеть неудачу (например, при фактическом рендеринге).

Если у кого-то есть мысли по поводу этого решения или, что еще лучше, более удачного способа найти значение, тогда это было бы замечательно.

Ответы [ 3 ]

3 голосов
/ 05 января 2010

Немного покопавшись, я создал следующий метод расширения, который использует отражение для извлечения значения флага 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. Это поле объявлено с внутренним типом, поэтому требуется больше отражения для вызова метода получения его свойства индексатора.

Метод расширения был протестирован на следующей разметке:

<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
0 голосов
/ 11 декабря 2014

Если кто-то попытается заставить код Йорна Шоу-Роде работать в 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
0 голосов
/ 05 января 2010

Вы можете выставить видимость элементов управления с помощью свойства. Это может решить вашу проблему.

Пожалуйста, поправьте меня, если я ошибаюсь.

...