Asp.net Usercontrol LoadControl の問題
-
04-07-2019 - |
質問
使用中に問題が発生しました LoadControl( type, Params )
. 。説明しましょう...
非常に単純なユーザー コントロール (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 }));
Message パラメーターをコンストラクターに渡したいため、LoadControl のオーバーロードされたバージョンを使用しています。このすべて 表示されます 大丈夫です。
ただし、 OnPreRender()
ErrorDisplay ユーザーコントロールで起動され、lblTitle 変数と lblDescription 変数は両方とも null
, 同等のマークアップがあるにもかかわらず。メッセージ変数が正しく設定されています。
なぜこれが起こっているのか誰かが解明できますか?
ありがとう
編集:
明確にするために、ユーザー コントロールをプログラムでページに追加するコードはボタンの押下に応答して実行されているため、「ホスティング ページ」は Init、Page_Load を経て進行し、現在イベント ハンドラーを処理していることも付け加えておきます。
ユーザー コントロールはボタン クリック イベントに応答して作成されるため、ASP ライフサイクルの初期段階で追加できません。
解決
次のコードも試してみました-同じ結果になります(つまり、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から:
コントロールをコンテナコントロールにロードすると、コンテナは現在のイベントに追いつくまで追加されたコントロールのすべてのイベントを発生させます。ただし、追加されたコントロールはポストバックデータ処理に追いつきません。追加されたコントロールを検証を含むポストバックデータ処理に参加させるには、LoadイベントではなくInitイベントにコントロールを追加する必要があります。
したがって、LoadControlはコントロールを正しく初期化すべきではありませんか?
編集:
わかりましたので、ここで自分の質問に答えています。.
上記にリンクしたフォーラム投稿の回答版が見つかりましたこちら
本質的に答えは、 LoadControl(type、params)
は解析するために 'page infront' ascxを推測できないため、どのコントロールも初期化されないということです。 LoadControl(&quot; ascx path&quot;)
バージョンを使用すると、ページが前面に表示されるため、すべての解析と初期化が行われます。
したがって、要約すると、コントロールを初期化するコードを変更し、別の部分に分割する必要があります。つまり、
Control ErrorCntrl = LoadControl("ErrorDisplay.ascx");
ErrorCntrl.ID = SomeID;
(ErrorCntrl as ErrorDisplay).SetErrorMessage = MessageDetail;
divErrorContainer.Controls.Add(ErrorCntrl);
そして、それはうまくいくはずです。それは私の以前の試みほどきれいではありませんが、少なくともそれは動作します。
上記を改善するための提案を引き続き受け付けています。
乾杯
他のヒント
Mitchelに同意すると、コントロールが完全に使用可能になった後に起動するpage_loadをコントロールコード自体に配置できるはずです。
まあ、常に独自のロードイベントを追加して、コンストラクタを実行してページにコントロールを追加した後に呼び出しますが、スタイルの理由から選択するかもしれませんが、それはあなたが持っているものと大差ありません。
問題の答えが見つかりました!
ここ は Steven Robbins によって書かれたブログ投稿です。この投稿では、次を使用してユーザー コントロールのパラメーターを渡す方法について説明します。 LoadControl
, 、何に似ていますか LoadControl(Type, object[])
そうするだろう、 それが機能することを除いて :)
e.Cell.Controlsコレクションにユーザーコントロールを追加したいという点で、CalendarコントロールのDayRenderイベントで同様の問題が発生しました。ユーザーコントロールpage_loadが起動しないか、ascx上のリストボックスがnull例外をスローして、いくつかの失敗したアプローチを試した後、LoadControl(ascx)を使用してフォームのコントロールを初期化し、 ascx、すべてがうまくいきました。このアプローチは、ascxのPage_Loadイベントにまったく依存しません。
ASCXマークアップ
コードビハインド
パブリッククラスCPCalendarCell System.Web.UI.UserControlを継承します
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マークアップ
フォーム上のCalendar DayRenderイベントの背後にあるコード
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
asp.netページのライフサイクルごとに、プリレンダリングでコントロールが完全に追加されていません。page_loadに値をロードしてみませんか?