How to access a top level master page sub from within a nested page?

574 Views Asked by At

MASTER PAGE STRUCTURE

TOP MASTER
    PAGE MASTER "TopMaster.ErrorMsg(ErrMsg) Here throws NO error"
        PAGE "TopMaster.ErrorMsg(ErrMsg) Here throws error"

I am unable to gain access to the top level class from the base page.

TOP MASTER ASPX

<asp:Literal ID="litMsg" runat="Server"/>

PAGE.VB

Partial Public Class BasePage
  Inherits System.Web.UI.Page

  Public Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    TopMaster.ErrorMsg(ErrMsg) 
    "Error BC30451: TopMaster is not declared it may be inaccessible due to its protection level."
  End Sub

End Class

MASTER.VB

Partial Public Class PageMaster
  Inherits System.Web.UI.MasterPage

End Class

TOP MASTER.VB

Partial Public Class TopMaster
  Inherits System.Web.UI.MasterPage

  Public Shared Sub ErrorMsg(ErrMsg As String)
    Dim myPage = TryCast(HttpContext.Current.Handler, Page)

    If myPage IsNot Nothing Then
      Dim master = myPage.Master
      Dim myMaster = TryCast(master.Master, TopMaster)
      While master.Master IsNot Nothing AndAlso myMaster Is Nothing
        master = master.Master
        myMaster = TryCast(master, TopMaster)
      End While

      myMaster.litMsg.Text = ErrMsg
    End If

  End Sub

End Class
1

There are 1 best solutions below

6
On BEST ANSWER

Update: now it's clear, make the class Public, otherwise you can't access it:

Partial Public Class TopMaster

You should show us the exact error message including stacktrace. It seems that the type Top Master is not declared which makes no sense since you are in the class TopMaster.

So i doubt that following fixes your core issue "Error: Top Master is not declared" but it might be useful anyway.

If you want to access that literal you should provide a property in your TopMaster like this:

Public Property ErrorMsg As String
    Get
        Return Me.litMsg.Text
    End Get
    Set(value As String)
        Me.litMsg.Text = value
    End Set
End Property

On this way you can even change the control-type if you want without breaking the code. Its much better than to expose the control itself.

I guess you also have to move the assignment from inside the loop to outside. You should also use Dim myMaster = TryCast(master, TopMaster) at the beginning instead of jumping directly to the page's master's master as you do with TryCast(master.Master, TopMaster):

Public Shared Sub ErrorMsg(ErrMsg As String)
    Dim myPage = TryCast(HttpContext.Current.Handler, Page)

    If myPage IsNot Nothing Then
        Dim master = myPage.Master
        Dim myMaster = TryCast(master, TopMaster)
        While master.Master IsNot Nothing AndAlso myMaster Is Nothing
            master = master.Master
            myMaster = TryCast(master, TopMaster)
        End While
        myMaster.ErrorMsg = ErrMsg
    End If

End Sub

Otherwise you are only assigning the ErrorMsg if the master is the page's master's master's master or it's even more deeply nested.