Search code examples
asp.netvb.netuser-controls

Why is my UserControl Visible property always returning false?


I have an issue where the Visible property on my user control is always returning False despite whether it should be visible on the page or not. I have the following user control:

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="WebUserControl1.ascx.vb" Inherits="VB_WebApp_Test.WebUserControl1" %>
<h1>My User Control</h1>
Public Class WebUserControl1
    Inherits UserControl

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.PreRender
        If Visible Then
            Console.WriteLine("VISIBLE")
        End If
    End Sub

End Class

That I load into the following page:

<%@ Page Title="Home Page" Language="VB" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.vb" Inherits="VB_WebApp_Test.Default" %>
<%@ Register src="WebUserControl1.ascx" tagName="WebUserControl" tagPrefix="Mine"%>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
    <asp:UpdatePanel runat="server">
        <ContentTemplate>
            <table>
                <tr>
                    <td>
                        <asp:MultiView runat="server" ID="multiView">
                            <asp:View ID="vInit" runat="server">
                                <h1>Initial View</h1>
                                <asp:Button runat="server" ID="toControlButton" Text="To Control"/>
                            </asp:View>
                            <asp:View ID="vControl" runat="server">
                                <Mine:WebUserControl ID="wuc1" runat="server"/>
                                <asp:Button runat="server" ID="toNonControlButton" Text="To Non Control"/>
                            </asp:View>
                        </asp:MultiView>
                    </td>
                </tr>
            </table>
        </ContentTemplate>
    </asp:UpdatePanel>
</asp:Content>
Public Class [Default]
    Inherits Page

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
        multiView.ActiveViewIndex = 0
    End Sub

    Public Sub ToControl(sender As Object, e As EventArgs) Handles toControlButton.Click
        multiView.ActiveViewIndex = 1
    End Sub

    Public Sub ToNonControl(sender As Object, e As EventArgs) Handles toNonControlButton.Click
        multiView.ActiveViewIndex = 0
    End Sub

End Class

What I would like to do is make it so that I can do some initialisation logic when the user control will be displayed, but the Visible property is always set to False. I have tried hooking onto the Load, PreRender and Init events, and the Visible property is False for all of them.


Solution

  • When your ActiveViewIndex is updated in Click event of button, the sequence of event is:

    1) Load for Page, ActiveIndex is 0, UC is not visible.

    2) Load for UserControl, UC is not visible due to invisible View

    3) Processing of events, ActiveIndex is updated to 1, Visibility property is updated for all related controls

    4) Page.LoadComplete event (Visible is True already, but you do not have the event)

    5) Page.PreRender (Visible is True already, but you do not have the event yet)

    6) UC.PreRender - here you should see Visible=True.

    I've just tedsted this on empty project and it works. You've must missed something when checking the PreRender event.

    Init based on Visibility is not very good practice. I suggest you to add some initialization like this:

    Public Sub Init()
        'Do init here
    End Sub