2008-10-27 75 views
15

我使用LoadControl(type, Params)時,有一個問題。讓我來解釋......Asp.net用戶控件LoadControl問題

我有一個超級簡單的用戶控件(ASCX)

<%@ Control Language="C#" AutoEventWireup="True" Inherits="ErrorDisplay" Codebehind="ErrorDisplay.ascx.cs" EnableViewState="false" %> 

<asp:Label runat="server" ID="lblTitle" /> 
<asp:Label runat="server" ID="lblDescription" /> 

與代碼(C#)的背後:

public partial class ErrorDisplay : System.Web.UI.UserControl 
{ 

    private Message _ErrorMessage;  

    public ErrorDisplay() 
    { 
    } 

    public ErrorDisplay(Message ErrorMessage) 
    { 
     _ErrorMessage = ErrorMessage; 
    }  

    protected override void OnPreRender(EventArgs e) 
    { 
     base.OnPreRender(e); 

     if (_ErrorMessage != null) 
     { 
      lblTitle.Text = _ErrorMessage.Message; 
      lblDescription.Text = _ErrorMessage.Description; 
     } 
    } 
} 

別處在我的web應用程序我加入使用下面的代碼的用戶控件的頁面的實例:

divValidationIssues.Controls.Add(LoadControl(typeof(ErrorDisplay), new object[] { MessageDetails })); 

我使用的重載版本LoadControl,因爲我想將Message參數傳遞給構造函數。所有這一切出現工作正常。

但是,當在ErrorDisplay usercontrol上觸發OnPreRender()時,lblTitle和lblDescription變量均爲null,儘管它們具有等價的標記。消息變量已正確填充。

任何人都可以闡明爲什麼這可能會發生任何輕?

感謝

編輯:

只是爲了清楚起見,我還要補充一點,這是編程添加用戶控件的頁面的代碼響應按鈕按下時運行,所以「託管頁面「已經通過Init,Page_Load進行並且正在處理事件處理程序。

,因爲它們是在響應按鈕單擊事件正在創建我不能在較早的asp生命週期階段添加用戶控件。

回答

19

我曾嘗試下面的代碼,以及 - 這將產生相同的結果(即lblTitle和lblDescription都爲null)

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (_ErrorMessage != null) 
    { 
     lblTitle.Text = _ErrorMessage.Message; 
     lblDescription.Text = _ErrorMessage.Description; 
    } 
} 

我有這樣的LoadControl功能把它加載到控制的理解其所在頁面的當前「狀態」。因此Init,Page_Load等都作爲LoadControl調用的一部分運行。

有趣的是這個(未回答)asp.net論壇發佈展品同樣的問題,因爲我經歷。

MSDN Forums Post

此外 - 從MSDN:

當加載控制到一個容器控件,容器引發所有添加控件的事件,直到它已經趕上當前事件。但是,添加的控件不能跟上回發數據處理。爲了增加控制參與回發數據處理(包括驗證),必須將控件添加到Init事件中,而不是Load事件中。

因此不應該正確LoadControl initalise控制?

編輯:

好了,我回答我的問題在這裏..

我發現論壇後我聯繫到上述Here

本質答案的回答版本是LoadControl(type, params)無法推斷'頁面infront'ascx解析,因此它並沒有擾亂任何控制。當你使用LoadControl("ascx path")版本時,它被賦予頁面infront,因此完成所有的解析和initalision。

所以總而言之,我需要改變這個代碼,這個代碼是將控件初始化並將它分成單獨的部分。即

Control ErrorCntrl = LoadControl("ErrorDisplay.ascx"); 
ErrorCntrl.ID = SomeID; 
(ErrorCntrl as ErrorDisplay).SetErrorMessage = MessageDetail; 
divErrorContainer.Controls.Add(ErrorCntrl); 

它應該可以正常工作。它不像我以前的嘗試那麼整潔,但至少它會工作。

我仍然願意提出改進上述建議。

乾杯

+3

+1和我的謝謝你解決我遇到的問題。 :) – 2008-12-27 12:06:09

-1

%的asp.net頁面生命週期的控制並沒有完全在預渲染,你爲什麼不只是加載值加在Page_Load中?

+1

上這是不正確的。 [PreRender在加載後發生](http://msdn.microsoft.com/en-us/library/ms178472.aspx#lifecycle_events)`在頁面對象創建所有控件後引發' – Chris 2011-05-24 00:26:09

0

與米切爾達成一致,你應該能夠把Page_Load中的控制代碼本身的控制是完全可以後這將觸發。

+1

[PreRender在*加載後發生] (http://msdn.microsoft.com/en-us/library/ms178472.aspx#lifecycle_events),所以PreRender應該是安全的。 – Chris 2011-05-24 00:27:53

0

嘛總是有添加自己的加載事件,並調用它,你已經跑構造並添加控件到頁面後,但它並不比你有什麼不同了很多,雖然我可能會選擇它出於風格的原因。

很高興你找到了你的問題的答案!

0

Here是由史蒂芬羅賓斯寫的博客文章。帖子介紹瞭如何傳遞參數使用LoadControl,類似於LoadControl(Type, object[])會做一個用戶控件,除了它的工作原理 :)

0

我曾與Calendar控件的DayRender事件類似的問題,我想補充e.Cell.Controls集合的用戶控件。在用戶控件page_load沒有觸發或者ascx上的列表框沒有引發null異常的情況下嘗試了一些失敗的方法後,我發現如果我使用LoadControl(ascx)初始化表單上的控件,然後開始訪問標記控件ascx,一切正常。這種方法根本不依賴於ascx上的Page_Load事件。

ASCX標記

背後

公共類CPCalendarCell 繼承System.Web.UI程序代碼。背後日曆的DayRender事件用戶控件

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 

End Sub 

Public Sub Add(txt As String) 
    Dim li As New ListItem(txt, txt) 
    lstDay.Items.Add(li) 
End Sub 

末級

頁ASPX標記

代碼的形式

Private Sub Calendar1_DayRender(sender As Object, e As System.Web.UI.WebControls.DayRenderEventArgs) Handles Calendar1.DayRender 
    Dim div As CPCalendarCell = LoadControl("~/UserControls/CPCalendarCell.ascx") 
    div.ID = "dv_" & e.Day.Date.ToShortDateString.Replace(" ", "_") 

    **e.Cell.Controls.Add(div)** 

    div.Add(e.Day.Date.Month.ToString & "/" & e.Day.Date.Day.ToString) 
    div.Add("Item 1") 
    div.Add("Item 2") 
    e.Cell.Style.Add("background-color", IIf(e.Day.IsWeekend, "whitesmoke", "white").ToString) 
End Sub