aspコンテンツタグのMasterPageとContentPlaceHolderIDを動的に変更しますか?

私はMastePage.masterから最初に継承されたページを持っています。そして私は、同じページを使用したいが、私のプロジェクトの別の場所で異なるマスターページ(MasterPage2.master)を使用したい。そのために私は次のコードを使用しています。

private void Page_PreInit(object sender, EventArgs e)
    {
        if (Request.QueryString["Update"].ToString() == "New")
        {
            this.MasterPageFile = "MasterPage2.master";
            Content con = new Content();
            con = (Content)this.FindControl("Content1");
            this.Content1.ContentPlaceHolderID = "ContentPlaceHolder2";
        }
    }

私はまた、MasterPage2.masterからのContentPlaceHolder2にaspコンテンツタグのContentPlaceHolderIDを設定しようとしています。最初はContentPlaceHolder1でした。

しかし、con =(Content)this.FindControl( "Content1");でnull値を取得しています。

ありがとう

1
ちなみに、Pagesはマスターページから「継承」しません。彼らはすでに彼らが継承している基本型を持っています。単にマスターページを参照し、その中にレンダリングします。
追加された 著者 Andrew Barber,
どうすれば同じページを参照して、このようなエラーが発生した別のマスターページを使用するのですか?マスターページ 'MasterPage2.master'にContentPlaceHolder 'ContentPlaceHolder1'が見つかりません。コンテンツページのContentPlaceHolderID属性を確認してください。
追加された 著者 Tiger,

3 答え

ページは内部的にプライベート '_contentTemplateCollection'ハッシュテーブルに格納されます。 ContentPlaceHolderIDプロパティをキーとして使用し、(コンテンツタグを構築/初期化するために使用される)特別なクラスを値として格納します   - ContentPlaceHolderIDの値(マークアップ内で定義されている)を変更するには、このハッシュテーブルを変更する必要があります。古いIDにリンクされている古いエントリを削除し、新しいIDで他のエントリを追加します   - マスターページを作成する前にContentPlaceHolderIdを変更する必要があります。それ以外の場合は、実行時に例外がスローされます   - Idを変更するのに最適な場所は、ページ 'preinit'イベントで、マスターページを変更する前にIDを変更する方が良い場合(実行時にマスターページを変更する場合)

コンテンツタグのContentPlaceHolderIDを変更するには、Page PreInitイベントで次の関数を使用できます

public static void AssignContentToNewPlaceHoldersWithinPage(Page pPage, string pOldId, string pNewId)
{
    if (pPage == null || string.IsNullOrEmpty(pOldId) || string.IsNullOrEmpty(pNewId))
    {
        return;
    }
   //Try to get a reference to private hashtable using fasterflect free reflection library in codeplex (http://fasterflect.codeplex.com/)
   //you can replace following line with standard reflection APIs
    var lTmpObj = pPage.TryGetFieldValue("_contentTemplateCollection");
    if (lTmpObj != null && lTmpObj is Hashtable)
    {
        var _contentTemplateCollection = lTmpObj as Hashtable;

        if (_contentTemplateCollection.ContainsKey(pOldId) && !_contentTemplateCollection.ContainsKey(pNewId))
        {
            var lTemplate = _contentTemplateCollection[pOldId];
            _contentTemplateCollection.Add(pNewId, lTemplate);
            _contentTemplateCollection.Remove(pOldId);
        }

    }
}
  • 関数のパラメータは
  • pPageはコンテンツタグを含むページインスタンスへの参照です。
  • pOldIdはマークアップのContentPlaceHolderIdプロパティ値です - 変更したいIDです。
  • pNewIdは使用したい新しいIDです。

私の答えが役に立つと思っています。私の英語が良くない

2
追加された

実行時にマスターページを動的に変更できますが、同じContentPlaceHolder IDを使用する必要があります。そうすれば、実行中にIDを変更するための特別なコードを追加することなく、どちらのマスターページでもページが動作します。

private void Page_PreInit(object sender, EventArgs e)
{
    if (Request.QueryString["Update"].ToString() == "New")
    {
        this.MasterPageFile = "MasterPage2.master";
    }
}

You can even test that your page will work with either Master Page in the Visual Studio design/markup view by changing the MasterPageFile in the <% Page %> directive in the .aspx markup.

0
追加された

マスターページは、OnPreInitをオーバーライドすることによって変更できます。

protected override void OnPreInit(EventArgs e)
{
    base.OnPreInit(e);
    MasterPageFile = "~/MasterPages/MyOther.Master";
}

しかし、ContentPlaceHoldersの場合は、両方のMasterPagesに同じ名前の新しいContentPlaceHoldersを作成することをお勧めします。

0
追加された