Add html layout to a blank aspx page - c#

Want to create dynamic html layout without any asp controls. Actually I want to leave on aspx page only the first line
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Kletka._Default" %>
and the generate full html layout on codebehind. Advise pls how to implement this.

One way is this:
protected void Page_Load(object sender, EventArgs e)
{
string coolHTML = #"<div class=""someclass"">... and other cool content</div>";
Response.Write(coolHTML);
}
With that said. This is a terrible idea. Constructing HTML dynamically on code behind is a nightmare to maintain, it doesn't perform as best as it can and you lose many other features that asp.net offers, which are the main reason to use ASP.NET in the first place.
What you can do is create User controls for specific things (footer, header, left panel, etc) and define a layout for them in markup; then on Code behind, you can add them to specific place holders in the page, depending on some business conditions.
Assuming you have a master page (or at least some content place holders in the page) as so:
<asp:ContentPlaceHolder id="footer" runat="Server" />
On code behind you can do:
footer.Controls.Add(new FooterControl());
Update OP just mentioned in the comments that he doesn't like asp.net controls...
You don't have to use ASP.NET controls, you can use regular HTML controls and set their runat="server" attribute if you need to be able to manipulate their properties on server-side. For example:
<div id="mydiv" runat="server" > some content </div>
On Code behind:
myDiv.Attributes.Add("class","css_class");
myDiv.Attributes.Add("onclick","callJavascriptFunction();");
// and so on.
It's okay to do this sort of thing occasionally under very specific circumstances but I'd avoid this sort of code because is difficult to maintain. Imagine you need to add another class to the myDiv element, for example. Now, you'd have to change you code as opposed to just changing your markup...

So...you want to use ASP.NET web forms without using the built in controls like GridView and so on, at all?
You can write your html and use protected properties?
<%= SomeWhereText %?
or to have the FULL html layout in the code behind make a property
protected string MyEntirePage {get;set;}
and build the string in the code behind
MyEntirePage="<h1>Hello</h1><p>body here</p><p>the end</p>";
and write it out in the aspx page via
<%=MyEntirePage%>
Re: "I've got your point, but I really don't like asp.net controls. I'd prefer to use html controls and customize them with js"
Install NancyFx or maybe the old (but still great) WCF Web Api and use something like KnockoutJs, jQuery or Backbone to perform ajax calls for the dynamic content = no asp.net web forms at all. Yay.

You would need to dynamically add the controls in the Page_Init event. So you need a container to hold your HTML, so you should start by adding a Panel to the Page, then the page's controls would get added to the Panel.
Panel pnl = new Panel();
Page.Controls.Add(pnl);
TextBox txt = new TextBox();
pnl.Controls.Add(txt);
etc....

Related

Adding ASP.NET User Controls at runtime via <script runat="server">

I am having trouble executing a control inside the <script runat="server"> tags in an *.aspx page.
The control works when it is defined declaratively in the HTML section of the page, but I am unable to make it work when placed within the script tag itself.
At the beginning of the page I register my control with:
<%# Register assembly="App_Web_exemple.ascx.cc671b29" namespace="Moncontrol" tagprefix="moncontrol" %>
Then, in the HTML, I call it (successfully) with the following declaration:
<moncontrol:exemple ISBN="9782894646151" runat="server" />
When I try to add it programmatically within the <script runat="server">, however, I am unable to execute it. I tried with the tags <asp:Text /> and <asp:Literal />, as follows, but that also doesn't doesn’t work.
In the HTML part:
<asp:Text id="TestControl" runat="server" />
In the script part
TestControl.Text = "<moncontrol:exemple ISBN=\"9782894646151\" runat=\"server\" />";
To clarify, what you're looking to do is programmatically add a User Control to your Web Forms page at runtime. There are a few ways of accomplishing this.
Before we begin, it's worth noting that the code you wrote likely "works" insomuch that it compiles and doesn't throw a runtime error. But it's also not executing the control. I suspect if you look at your HTML, you'll find the control declaration being output as a string literal (i.e., unprocessed by the server). It is then disregarded by the browser since it doesn't know what the <moncontrol:exemple /> tag represents. That's obviously not what you want.
Establishing a Control Container
Regardless of which approach you take, you'll want to start with some type of container on your page that you can add the control to, such as a Panel. If you don't want the container to output any wrapper markup, you can use a Placeholder:
<asp:Placeholder id="ControlContainer" runat="server" />
This serves a similar purpose as your current Text control, except its only purpose is to provide a container that you will add your user control to. From ASP.NET's perspective, however, this can be any type of server control, including a <script runat="server">, as per your request. More on that later.
Programmatically Creating the Control
Next, you're going to create the control programmatically. This is where we run into various options. The most universal approach is to use ParseControl() method (reference). This looks something like this:
Control control = Page.ParseControl("<%# Register assembly=\"App_Web_exemple.ascx.cc671b29\" namespace=\"Moncontrol\" tagprefix=\"moncontrol\" %><moncontrol:exemple ISBN=\"9782894646151\" runat=\"server\" />");
That will parse the control using the same method that processes the declarative syntax on the page, and return a Control object with your Exemple control as the first control in its Controls collection.
I find that syntax a bit sloppy, however, since it's representing a .NET object and its properties as a string literal. Given that, there are some cleaner approaches. In this case, it appears that your control is being compiled into an assembly and, therefore, likely has a Code Behind defined which inherits from UserControl. If so, you should be able to simply do something like:
Exemple control = new Exemple();
And then set the properties on it programmatically, the way you would in any other C# object. Much cleaner!
If your control was instead being compiled dynamically by the server, then you'd instead use the Reference directive with the LoadControl() method, as described in the MSDN article How to: Create Instances of ASP.NET User Controls Programmatically. I don't believe that method will work for you, however.
Adding the Control Instance to the Page
Regardless of which approach you take, the next step is the same: you then add the control you've programmatically added to your page by adding it to the Controls collection of the target container. E.g.,:
ControlContainer.Controls.Add(control);
Note: You can technically just add this to the Page class's Control collection, too, but that doesn't give you any control over where on the page it is placed; having a PlaceHolder control (or equivalent) lets you specify exactly where you want the control to appear.
I hope this helps. There are a couple of caveats depending on how you wrote and compiled your control, but this should give you the basic structure needed to address your problem.

How to programmatically add stuff to contentPlaceHolder?

I have a master page and all of my pages are inheriting it.
For formatting, I thought to place the content that differs from one page to another in a ContentPlaceHolder.
Now, how can I insert everything into that? Since I am planning to populate the ContentPlaceHolder with stuff from a database I suppose I will have to do it programmatically.
How can I add controls to ContentPlace Holder?
I checked other answers, but I cannot access it by its ID.
Should I use multiple ContentPlaceHolders from the beginning? Let's say I want to put movies. Should there be only one with all the images and descriptions and ratings, ore one ContentPlaceHolder for each thing?
I am opened to other solutions, as I have no experience with ASP.
Old question... but I just ran into this issue and this was the #1 post that kept coming up on Google, so figure I'd add my answer since the others didn't work in my case.
Here is how I did it when a regular <asp:Content wouldn't work (though in normal use, the answer #JayC is how you do it):
MasterPage has this ContentPlaceHolder:
<asp:ContentPlaceHolder ID="ScriptsPlace" runat="server"></asp:ContentPlaceHolder>
Had to dynamically add some JavaScript from a User Control. Trying to use the ContentPlaceHolder directly gives this error:
Parser Error Message: Content controls have to be top-level controls
in a content page or a nested master page that references a master
page.
So I wanted to add the script from the code-behind. Here is the Page Load for the .ascx file:
protected void Page_Load(object sender, EventArgs e)
{
ContentPlaceHolder c = Page.Master.FindControl("ScriptsPlace") as ContentPlaceHolder;
if (c != null)
{
LiteralControl l = new LiteralControl();
l.Text="<script type=\"text/javascript\">$(document).ready(function () {js stuff;});</script>";
c.Controls.Add(l);
}
}
UPDATE: So it turns out I had to use this in more places than I expected, and ended up using a way that was much more flexible / readable. In the user control itself, I just wrapped the javascript and anything else that needed to be moved with a regular div.
<div id="_jsDiv" runat="server">
$(document).ready(function() {
//js stuff
});
Other server controls or HTML junk
</div>
And then the code behind will find that div, and then move it into the ContentPlaceHolder.
protected void Page_Load(object sender, EventArgs e)
{
ContentPlaceHolder c = Page.Master.FindControl("ScriptsPlace") as ContentPlaceHolder;
HtmlGenericCOntrol jsDiv = this.FindControl("_jsDiv") as HtmlGenericControl;
if (c != null && jsDiv != null)
{
c.Controls.Add(jsDiv);
}
}
I actually put this code in a custom user control, and I just have my regular user controls inherit from the custom user control, so once I wrap the javascript/etc with a <div id="_jsDiv" runat="server">, the custom user control takes care of the rest and I don't have to do anything in the code behind of the user control.
What normally happens is
you set up your master pages with the proper html and ContentPlaceHolders
you create pages based off that master page. If you use Visual Studio, and tell it to create a new page based upon a existing Master page, it will add the Content areas for you.
you add things to the Content areas in the newly created page.
If you want to dynamically add controls to the master (or any) page, you could add controls to any existing control. If it shouldn't be wrapped in any way, just add a Placeholder (it is an asp.net control).
I did like this
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
<asp:Literal ID="jsstuff" runat="server"></asp:Literal>
</asp:Content>
And this went into code behind:
string stuff = #"<script type=""text/javascript"">
var searchBox = 0;
var currentCountry = '';
</script>";
jsstuff.Text = stuff;
If the namespace for content Page and Master page is not same then the content page control not accessible in Codebehind in content page.
Also, check your designer files. if the control not listed in designer file then delete the file and recreate (project->convert to web application)

Using a custom control more than once on the same page / form .net

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.

Similar Master pages, best way to DRY?

I have two similar master pages, basically they are pretty extensive, but the difference relies in one using
common content
<form id="form1" runat="server" enctype="multipart/form-data">
common content
</form>
common content
and the other being
common content
<dn:Form id="form1" runat="server">
common content
</dn:Form>
common content
I was wondering how I could accomplish this, without having to create two master pages and just changing the form tags...
The way I currently though of doing this, is basically have one master page with the other content, a second one with the inner contents, and two others that just have the form tags and a placeholder inside them, and then dynamically choosing one master page over the other.
Is there a better way to do this or is this the correct way? thanks.
Update: I'm not sure my current idea is well expressed:
Base.master would have the outer contents, no inheritance.
Regular and Modified.master would have just the different form tags, both inherit from Base.Master
Shared.master would have the inner contents, inherit from Regular.Master and in case it requires the other form control, then it chooses the other master (which has the same ContentPlaceHolderID for FormContent), dynamically with something like this, maybe reading from web.config or the like
protected void Page_PreInit(object sender, EventArgs e)
{
this.MasterPageFile = "~/App_Shared/RegularWebForm.Master";
this.MasterPageFile = "~/App_Shared/UrlRewritableWebForm.Master";
}
The goal for this is being able to use the same Master page across three different applications for one same web domain.
The idea that my solution proposed would be that I have those four master page files in a given "App_Shared" folder, which is referenced via svn:externals from all the projects, so I don't have to repeat the code. The idea would be that I choose whether Shared.Master (which would be the functional base master page file for all three applications) uses the regular form or the user control in the current application, and that choice could be made by a setting in the web.config for the application.
In the master page code behind, you should be able to override OnInit (or OnLoad or in any number of other places) and determine when you need multipart encryption, and when you do, call:
Attributes.Add("enctype", "multipart/form-data");
Even better:
Expose a boolean property:
public bool EncodeMe {get;set;};
In each form that uses the master control set
Master.EncodeMe = true; // or false of course
then in the master page use the bool to determine whether or not to encode.

Can you change a master page's ContentPlaceHolder's Content Page Asynchronously in .NET?

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.

Categories

Resources