Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • snitram 27 posts 48 karma points
    Jul 16, 2010 @ 08:38
    snitram
    0

    Access to contentPlaceHolders from usercontrol?

    I've got myself a new challenge :-)

    My template structure (simplified) is as follows:

    htmlMaster
     design
       normal
       products
       etc

    In the "htmlMaster", I've several contentPlaceHolders for title, javaScript and CSS includes and so forth. That way I can add titles directly from my specific templates and handle includes on sub template level, enabling me to cut away unnessesary script and CSS when I dont need it.

    My products are rendered through a Macro based on a Usercontrol. When ever details of a product is displayed, I would like to control the title for instance. I just can't figure out how to do this from my Usercontrol. I've looked into Masterpages, and my logic approach would be to do something like this:

    ContentPlaceHolder ph = (ContentPlaceHolder)Page.Master.FindControl("title");

    This always yields null :/

    Can anyone point me in the right direction? 

  • Folkert 82 posts 212 karma points
    Jul 16, 2010 @ 09:34
    Folkert
    0

    If you're trying to access nested master pages, I think you need the master of the masterpage. So I guess you'll need to use

    Page.master.master.findcontrol("title")

    If you put runat="server" on the title tag in your master,you don't need any placeholder. you can access the title directly:

    Page.master.master.Page.Title

    runat="server" is not needed as fas I can see. You can access the master page title directly as I mentioned above.

    Snippet

    // acces title in master
    this.Page.Master.Master.Master.Page.Title = "This is a test";
                
    // access textbox in master
    TextBox tb = (TextBox)this.Page.Master.Master.Master.FindControl("tbTest");           
    tb.Text = "Find control in masterpage";

     

  • snitram 27 posts 48 karma points
    Jul 16, 2010 @ 10:17
    snitram
    0

    Thanks for your suggestions so far!

    The code:

    Page.Master.Master.Page.Title = "my title" 

    Works just fine in my example (htmlMaster/design/products). The only problem is, that when I place my title ContentPlaceHolder (which I use from all other templates than "products" to set title), it doesn't work anymore.

    I also tried:

    Page.Master.Master.FindControl("myTitle")
    Page.Master.Master.Master.FindControl("myTitle") 

    Both returning null. "myTitle" is the Id of the ContentPlaceHolder tag in my "htmlMaster" template:

    <title><asp:ContentPlaceHolder Id="myTitle" runat="server"></asp:ContentPlaceHolder></title>

     

    Perhaps I should mention, that I need to set several values including meta tags and such from my "products" Usercontrol - so the solution must not be limited to title.

  • Ismail Mayat 4511 posts 10092 karma points MVP 2x admin c-trib
    Jul 16, 2010 @ 10:22
    Ismail Mayat
    0

    Martin,

    FindControl is not recursive maybe try http://geekswithblogs.net/AzamSharp/archive/2008/04/20/121438.aspx that is a recursive findcontrol function.

    Regards

    Ismail

  • Folkert 82 posts 212 karma points
    Jul 16, 2010 @ 10:22
    Folkert
    0

    You should use a Literal control for the title. Contentplaceholder is used for (nested) masterpages.

    Snippet

    <title><asp:Literal ID="litTitle" runat="server" /></title>

  • snitram 27 posts 48 karma points
    Jul 16, 2010 @ 10:32
    snitram
    0

    Ok Folkert,

    I sence that my approach using ContentPlaceHolders is wrong - regarding adding title, javascript, css, meta etc. from sub templates. Can you explain how I should approach the issue instead?

  • Thomas Enggaard Christensen 24 posts 49 karma points
    Jul 16, 2010 @ 10:36
    Thomas Enggaard Christensen
    0

    If you have a runat="server" on the <head> html tag on your master page (<head runat="server">) you should be able to set the title from any page with:

    this.Title = "The page title";

    and from any usercontrol with:

    this.Page.Title = "The page title";

    You dont need to go up through the master pages to do that.

  • snitram 27 posts 48 karma points
    Jul 16, 2010 @ 10:40
    snitram
    0

    You are right enggaard - but what is the cleanest way, of implementing the possibility of using "Page.Title" from a Usercontrol and possibility of setting the title from templates or xslt as well?

  • Ismail Mayat 4511 posts 10092 karma points MVP 2x admin c-trib
    Jul 16, 2010 @ 10:41
    Ismail Mayat
    0

    Guys,

    If you have runat at server in the head tag any macros and umbraco:item calls will render out literally its a know issue not sure if its fixed in latest version see http://our.umbraco.org/forum/umbraco-pro/contour/9213-macro-and-item-issue-when-head-runat-server

    Regards

    Ismail

  • Folkert 82 posts 212 karma points
    Jul 16, 2010 @ 10:49
    Folkert
    0

    Okay, here we go, for a base setup:

    master.master:

    Snippet

    <%@ Master Language="C#" AutoEventWireup="true" CodeBehind="master.master.cs" Inherits="test.master" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title><asp:ContentPlaceHolder ID="cphTitle" runat="server" /></title>
        <asp:ContentPlaceHolder ID="cphHead" runat="server" />
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:TextBox ID="tbTest" runat="server" />
            <asp:ContentPlaceHolder ID="cphContent" runat="server" />
        </div>
        </form>
    </body>
    </html>

    Design.master:
    Snippet

    <%@ Master Language="C#" MasterPageFile="~/master.Master" AutoEventWireup="true" CodeBehind="design.master.cs" Inherits="test.design" %>

    <asp:Content ID="Content3" ContentPlaceHolderID="cphTitle" runat="server">
         <asp:ContentPlaceHolder ID="cphTitle" runat="server" />
    asp:Content>

    <asp:Content ID="Content1" ContentPlaceHolderID="cphHeader" runat="server">
         <asp:ContentPlaceHolder ID="cphHeader" runat="server" />
    asp:Content>

    <asp:Content ID="Content2" ContentPlaceHolderID="cphContent" runat="server">
         <asp:ContentPlaceHolder ID="cphContent" runat="server" />
    asp:Content>

    products.master:
    Snippet

    <%@ Master Language="C#" MasterPageFile="~/design.master" AutoEventWireup="true" CodeBehind="products.master.cs" Inherits="test.products" %>

    <asp:Content ID="Content3" ContentPlaceHolderID="cphTitle" runat="server">
        <asp:ContentPlaceHolder ID="cphTitle" runat="server" />
    asp:Content>

    <asp:Content ID="Content1" ContentPlaceHolderID="cphHeader" runat="server">
        
        <script src="/js/test.js" type="text/javascript" />    
        <link rel="stylesheet" type="text/css" href="/css/products.css" />
        <asp:ContentPlaceHolder ID="cphHeader" runat="server" />
    asp:Content>

    <asp:Content ID="Content2" ContentPlaceHolderID="cphContent" runat="server">
        <asp:ContentPlaceHolder ID="cphContent" runat="server" />
    asp:Content>

    product.aspx:
    Snippet

    <%@ Page Title="" Language="C#" MasterPageFile="~/products.master" AutoEventWireup="true" CodeBehind="product.aspx.cs" Inherits="test.product" %>

    <asp:Content ID="Content1" ContentPlaceHolderID="cphTitle" runat="server">
        product title
    asp:Content>

    <asp:Content ID="Content2" ContentPlaceHolderID="cphHeader" runat="server">
        additional scripts
    asp:Content>

    <asp:Content ID="Content3" ContentPlaceHolderID="cphContent" runat="server">
        product content
    asp:Content>

    As you can see there is a masterpage -> design.master -> products.master and a sample page wich inherits the products.master.
    Specific script you can put in the master, without coding.
    Don't put too many different scripts and css in pages. A css file is not that large and will be cached by the browser. Using small page-specific js/css files will slow the site.

     

  • snitram 27 posts 48 karma points
    Jul 16, 2010 @ 11:05
    snitram
    0

    Thanks for the example. You are right, small files are best served always, so the browser can cache the files. My approach is more based on not including jQuery and a ton of extensions, if they are not needed.

    Thats pretty much my current setup, so maybe I'm missing something here - or not explaining my problem clearly enough :-)

    With that setup, my "product.aspx" page is a node created in Umbraco using my "products" template. In the "products" template, a Macro based on a Usercontrol renders the products. In the current setup, how do I set values of the different ContentPlaceHolders in my master.master?

  • Folkert 82 posts 212 karma points
    Jul 16, 2010 @ 11:53
    Folkert
    0

    So,you put a usercontrol(as a macro) in the product node page. From  the usercontrol you can access the controls from parents as mentioned in this thread before.
    If you would like to alter values from usercontrols, use actual controls and not contentplaceholders because they only serve as a placeholder in master page scenarios.

    You can't "set values" in a contentplaceholder, because they just don't have a 'value'. It's an indication for nested masterpages to use that space for content.

    If you would like to create values in the master, you can use a Placeholder control to add controls to: Placeholder.Controls.Add( etc... ).

  • snitram 27 posts 48 karma points
    Jul 16, 2010 @ 12:25
    snitram
    0

    Thanks for your patience :-)

    I follow you so far, and I'm fully aware of what a ContentPlaceHolder is. But in my mind, I should be able to create a "asp:Content" object from codebehind (should be the same as from design, no?), and add this object to the masterpages title ContentPlaceHolder, right? I cannot find out how - and I'm unsure wether this is Umbraco specific problem or general ASP.NET problem.

    I've also added a test PlaceHolder to my title in the master.master, but I cannot refer this PlaceHolder by either "Page.Master.Master.FindControl" or "Page.Master.Master.Master.FindControl". So how would you think I can refer this PlaceHolder?

  • Folkert 82 posts 212 karma points
    Jul 16, 2010 @ 12:53
    Folkert
    0

    In master.master:
    Snippet

    <head runat="server">
        <title>
            <asp:ContentPlaceHolder ID="cphTitle" runat="server" />
            <asp:PlaceHolder ID="phTitle" runat="server" />
        </title>
    In page control:
    Snippet
      protected void Page_Load(object sender, EventArgs e)
            {
                PlaceHolder ph = (PlaceHolder)this.Page.Master.Master.Master.FindControl("phTitle");
                Literal tb = new Literal();
                tb.Text = "new vallue";
                ph.Controls.Add(tb);
            }
    I don't think you can't set the asp:content via Code-behind. Maybe in page-init event?

Please Sign in or register to post replies

Write your reply to:

Draft