2012年10月17日 星期三

存取MaterPage變數

有時候我們有一些公用變數會放置在mastepage中方便每一呼叫,除了讓程式碼比較簡潔,也可以避免重複取得資料減少loading

 用法上很簡單,一個就是在masterpage中放置一個public變數

public partial class SiteMaster : System.Web.UI.MasterPage
{   
    public string UserID = "";
}

接著在內頁的地方就可以直接使用

    protected void Page_LoadComplete(object sender, EventArgs e)
    {       
        string UserID = ""
        User = (this.Master as SiteMaster).UserID;
//這裡有時候.net會秀斗,正常的話按點就會出現UserID那些全域變數可以選,但有時候又不會出來,甚至還出現編譯錯誤,原因不明
    }

在查資料過程中有看到有人提到,在aspx中要引用該masterpage,但實際測試的結果似乎是不用
<%@ MasterType VirtualPath="~/Site.master" %>

在使用的時候會碰到一些難題,因為內頁的PageLoad會早於masterpage的PageLoad,因此會造成如果將取得資料寫在masterpage中會造成內頁一開始時抓不到masterpage的值,因為此時masterpage的pageload尚未被觸發,此時就要考慮將內頁的程式碼寫在Page_LoadComplete中

但若使用Page_LoadComplete的話,如果畫面上有按鈕事件,在頁面中按下按鈕去觸發事件時,則系統會先觸發該頁面的page_load事件再觸發masterpage中的Page_load,然後直接觸發該頁面按鈕的事件,而不會觸發到該頁面的Page_LoadComplete,所以就會變成要再每一個按鈕的事件中去重新取得masterpage的全域變數值,因此每個事件都要自己去判斷masterpage那邊是否有取到值,沒有的話要return掉,不然程式可能因為沒取到值而發生錯誤

不過在這次的案例中,因為我的masterpage會判斷使用者有沒有登入而彈跳出視窗,此時內頁就要根據masterpage那邊的值去秀出一些畫面出來,因此我一定要寫在pageload,但寫在pageload我就又存取不到masterpage那邊的值,變成一個死循環,所以我最後我還是只能經由上次masterpage所取得的值存在cookie中在pageload時去取得

頁面執行順序參考如下:
如果以單一頁面來說執行順序如下:
Page.PreInit
Page.Init
Page.InitComplite
Page.PreLoad
Page.Load
Page.LoadComplete
Page.PreRender
Page.PreRenderComplete

如果頁面裡面包了一個Usercontrol 執行順序如下:
Page.PreInit
UserControl.Init
Page.Init
Page.InitComplete
Page.Load
UserControl.Load
Page.LoadComplete
Page.PreRender
UserControl.PreRender
Page.PreRenderComplete

如果在頁面裡面包了一個Usercontrol然後套用一個主版頁面 執行順序如下:
Page.PreInit
UserControl.Init
MasterPage.Init
Page.Init
Page.InitComplete
Page.Load
MasterPage.Load
UserControl.Load
Page.LoadComplete
Page.PreRender
MasterPage.PreRender
UserControl.PreRender
Page.PreRenderComplete

    
VS2010中居然不能夠直接使用IDE介面來產生一些頁面的事件,預設只有PageLoad,其他事件只能夠自己打,可以參考以下

protected void Page_PreInit(object sender, EventArgs e)
protected void Page_Init(object sender, EventArgs e) 


關鍵字
asp.net page 事件添加
叫出 asp.net 頁面 屬性表
page masterpage 執行順序
masterpage 變數

沒有留言:

張貼留言