动态更改asp内容标记的Master Page和ContentPlaceHolderID?

时间:2012-02-06 16:48:01

标签: c# asp.net

我有一个最初从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";
        }
    }

我也在尝试将asp内容标记的ContentPlaceHolderID设置为来自MasterPage2.master的ContentPlaceHolder2。最初是ContentPlaceHolder1。

但是我在con =(Content)this.FindControl(“Content1”);

获取空值

由于

3 个答案:

答案 0 :(得分:2)

页面内部存储在私有'_contentTemplateCollection'哈希表中。它使用ContentPlaceHolderID属性作为键,并将特殊类(将用于构建/初始化Content标记)存储为值   - 所以要更改ContentPlaceHolderID值(在标记中定义),您需要修改此哈希表,删除与旧ID链接的旧条目,并添加具有新ID的其他条目   - 您需要在创建母版页之前更改ContentPlaceHolderId,否则将在运行时抛出异常   - 更改Ids的最佳位置是Page'preinit'事件,如果在更改母版页之前更改ID更好(如果您将在运行时更改母版页)

要更改Content标签的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

我希望我的回答有用,如果我的英语不好,我很抱歉

答案 1 :(得分:1)

您可以在运行时动态更改母版页,但需要使用相同的ContentPlaceHolder ID。这样,您的页面将与主页面一起使用,而无需添加额外的代码来在运行时更改ID。

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

您甚至可以通过更改.aspx标记中MasterPageFile指令中的<% Page %>来测试您的页面是否可以在Visual Studio设计/标记视图中使用母版页。

答案 2 :(得分:0)

可以通过覆盖OnPreInit来更改母版页。

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

但对于ContentPlaceHolders,我建议在两个MasterPages中创建具有相同名称的新ContentPlaceHolders。