【问题标题】:Dynamically change MasterPage and ContentPlaceHolderID of asp content tag?动态更改asp内容标签的MasterPage和ContentPlaceHolderID?
【发布时间】:2012-02-06 16:48:00
【问题描述】:

我有一个最初继承自 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"); 处得到空值;

谢谢

【问题讨论】:

  • 顺便说一下,页面不会“继承”母版页。他们有一个他们已经继承的基本类型。他们只是引用一个母版页并在其中呈现。
  • 那么我如何引用同一页面以使用不同的母版页并出现这样的错误 --- 在母版页“MasterPage2.master”中找不到 ContentPlaceHolder 'ContentPlaceHolder1',验证内容控件的 ContentPlaceHolderID 属性内容页面。

标签: c# asp.net


【解决方案1】:

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

要更改 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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-05
        • 1970-01-01
        • 2011-10-29
        相关资源
        最近更新 更多