I am writing a webpart and was trying to update the browser title... so, I went into mywebpart.ascx added the following:
<asp:Content ID="contentPageTitle" ContentPlaceholderID="PlaceHolderPageTitle" runat="server">
<%= SPContext.Current.Site.OpenWeb().Title %>
</asp:Content>
I then got this error:
Content controls have to be top-level controls in a content page or a nested master page that references a master page.
So, I am trying to do it programatically in mywebpart.cs by doing:
Content content = new Content();
content.ContentPlaceHolderID = "PlaceHolderPageTitle";
I now need to input this piece: SPContext.Current.Site.OpenWeb().Title
What property in the Content control allows me to do that? If there is a better way to do this, I am open as well. Thanks.
Unfortunately, you cannot place a content control within a user control. As the error message indicates, content controls must be top level controls in a page or master page, and cannot belong in any other kind of control.
An alternate approach might be to customize your page layout or master page to contain the logic you want to provide.
If you have some assurance of the ID of the content control (not the ContentPlaceholderID, mind you), then you can interact with the content control like so:
var content = Page.FindControl("contentPageTitle");
content.Controls.Add(new LiteralControl("Hello, World!"));
--
On an aside, do ensure that any SPWeb opened with OpenWeb() gets disposed properly, or you may face memory management problems down the road.
Related
I have been building a custom control for some time now and overcome a number of hurdles. One challenge I have yet to resolve is the ability to use a custom control more than once on the same page.
I have a custom control that functions well on its own, but when two of the same controls are placed on the page the second control is able to control the first one. My guess is that the first one (control) is the first object and the second one is the same object. How can I make sure in the code that if I use the same control more than once on a page it will behave as two separate controls. Are there any specific things I should look at to make sure it allows it to be on a page more than once.
Thanks in advance.
When you add multiple instances of a control, be sure to give them different IDs. Then when writing any code that will interact with them, reference them by that ID.
<%# Register Src="controls/myControl.ascx" TagName="myControl" TagPrefix="uc1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainPlaceHolder" runat="server">
<uc1:myControl ID="ctlFirst" runat="server">
<uc1:myControl ID="ctlSecond" runat="server">
</asp:Content>
Then in the code behind:
ctlFirst.SomeProperty = true;
ctlSecond.SomeProperty = false;
Place a couple of instances of your custom control onto an ASPX page then view the HTML source and have a look at all the element IDs generated on each of the control instances. ASP.NET will automatically mangle the IDs of your control's children, prefixing them with the ID of the parent control. If you're outputting raw HTML, this might not happen. If there are any duplicate IDs, then that may be the cause of your problem, particularly if you're using client-side logic to manipulate the controls on the page.
Also, make sure that you're not using any session or application variables in your controls.
I have a problem with dynamically loading control's into master page's ContentPlaceHolder.
Name of the ContentPlaceHolder and path of the UserControl is loaded from db and send to this little code:
Control c = this.Page.LoadControl(uc-path-from-db);
this.Page.Master.FindControl(cph-name-from-db).Controls.Add(c);
When I run it, I get this error:
The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).
What am I doing wrong?
Its not totally clear without your markup, but it is telling you that you can't Add the control in there because some of your markup contains a <% ... %> block which tells ASP.NET to execute whatever is in there to create your markup. Try removing your <% ... %> block and it should let you Add the control. Or post your markup for a more complete answer.
Depending on the type of Web Project you're working with, you have to be sure to <%# Register%> your UserControl on both the MasterPage you're loading it to, and the Page you're loading it from. If you're working with a web site and not a web application it compiles each page into it's on little assembly and won't reference the usercontrol's assembly unless it sees that Reference tag in the markup.
I'm not 100% on this, but it's worth a look.
I'm looking for a way to (preferably) strongly type a master page from a user control which is found in a content page that uses the master page.
Sadly, you can't use this in a user control:
<%# MasterType VirtualPath="~/Masters/Whatever.master" %>
I'm trying to access a property of the master page from the user control and would rather not have to pass the property from the master page to the content page to the user control because multiple content pages use the same user control. One change, one place whatnot.
Try Page.Master.
Whatever whatev = (Whatever)Page.Master;
You'll have to make sure you add the proper using statements to the top of your file, or qualify the Master page type inline.
One potential gotcha is if this control is used by a different page whose master page is NOT the same type. This would only get caught at runtime.
Have you tryed Page.FindControl("name") on the usercontrol?
The best way to do it that I've found is actually to build a custom class that is based off of UserControl, give it a Master property with a get accessor that fishes through the this.Page.Parent until it stops encountering master pages (If you are nesting, this step is unnecessary otherwise) and then return that web control as the type of the master page you want to use. Then, when you add a new user control, change it's base class to the name of your custom class. The .Master property will be accessible and cast properly as the master page you want it to use.
In VB all I needed to do was change this:
Dim lAuthLevel As Integer = Master.MasterContact.AuthenticationLevel
to this:
Dim lAuthLevel As Integer = CType(Me.Page.Master, main).MasterContact.AuthenticationLevel
So all references of Master become Ctype(Me.Page.Master, typeofMaster)
Where is in this case the word "main" - get that from the declaration at the top of the master page. e.g.
So "main" in this case :)
From what I've already read this appears to be impossible, but I wanted to see if anyone out there has a secret trick up their sleeve or at least a definitive "no".
Supposedly a master page is really just a control for a content page to use, not actually the "master" of a content page. If I wanted to go from one content page, to another content page with the same master page, I would just say
Response.Redirect("PageB.aspx");
But this would immediately cause a postback, flickering the page, which is the crappy pre-ajax way of doing things.
In this current project, I'm trying to see if I could figure out how to change the current content page of a ContentPlaceHolder in the master page asynchronously, when a button is clicked on the master page.
Is this possible, if so how?
I don't know if you can between pages (.aspx) but it can definitely be done using UserControls.
ASP.Net pages each have their own URL so what you're trying to do is to go from one URL to another without any postback, that's just not how it's supposed to work.
Using user controls (.ascx):
Create a page that uses the MasterPage and use something like this in the content
<ajax:UpdatePanel ...>
<ContentTemplate>
<asp:PlaceHolder ...>
</ContentTemplate>
</ajax:UpdatePanel>
Search for UpdatePanel and tweak its settings to do what you want, then learn how to swap user controls in a placeholder.
No, you cannot because a master page is actually a control rendered on a particular aspx page, rather than actually containing the aspx page as it deceptively appears to be programmatically and in design view.
More Info:
You could however use a variety of other controls to simulate this effect. The asp:MultiView control is one example, each "page" could be made in a single view and placed in an update panel, thus allowing it to be switched asynchronously. Alternatively you could define each page in a separate user control and put those in an update panel, asynchronously switching the visible property on those controls as needed.
There are really a lot of different ways to achieve an effect similar to changing the master page's content placeholder.
I specifically want to add the style of background-color to the <body> tag of a master page, from the code behind (C#) of a content page that uses that master page.
I have different content pages that need to make the master page has different colors depending on which content page is loaded, so that the master page matches the content page's theme.
I have a solution below:
I'm looking for something more like:
Master.Attributes.Add("style", "background-color: 2e6095");
Inside of the page load function of the content page. But I can't get the above line to work. I only need to change the background-color for the <body> tag of the page.
What I would do for the particular case is:
i. Define the body as a server side control
<body runat="server" id="masterpageBody">
ii. In your content aspx page, register the MasterPage with the register:
<% MasterPageFile="..." %>
iii. In the Content Page, you can now simply use
Master.FindControl("masterpageBody")
and have access to the control. Now, you can change whatever properties/style that you like!
This is what I came up with:
In the page load function:
HtmlGenericControl body = (HtmlGenericControl)Master.FindControl("default_body");
body.Style.Add(HtmlTextWriterStyle.BackgroundColor, "#2E6095");
Where
default_body = the id of the body tag.
I believe you are talking about a content management system. The way I have delt with this situation in the past is to either:
Allow a page/content to define an extra custom stylesheet or
Allow a page/content to define inline style tags