 |
|
 |
Not sure if during my modifications I've done something to break this code but none of the validators on my page were working. I had to add the following code to get them to work (although I haven't yet completely tested this solution so it's supplied as is without warranty ):
//-------------------------------------------------------
foreach(Control control in content.Controls)
{
if(control is IValidator)
{
this.Validators.Add(((IValidator)control));
}
}
I placed this just before the findcontrol("Form1") line.
I hope this helps someone in a similar situation.
|
|
|
|
 |
|
 |
Further testing reveals one of my suspicions that this would not work for nested controls (ie something within an INamingContainer). Therefore I have altered the code to a (shock horror) recursive function:
private void addValidators(Control parentControl)
{
foreach(Control childControl in parentControl.Controls)
{
if(childControl is IValidator)
{
this.Validators.Add(((IValidator)childControl));
}
else
{
addValidators(childControl);
}
}
}
where it is called via:
addValidators(content);
I'm still not sure of the theory why the controls.add does not link up the control collection to activate the validators in their original location but currently will be happy if I can just test the site with validation.
|
|
|
|
 |
|
 |
You Wish...
It does not end there.
It seems that this problem has no straightforward solution.
If you do that thing with the validators, then I would recommend testing a page with a DataGrid inside it. Make sure that you bind it to data from a datasource onlu on the first time: if(!IsPostBack), then in subsequent requests the data (in normal sercumstances) should appear the same in the datagrid (without rebinding) since the DataGrid gets rebuilt from the ViewState.
Unfortunately, when you solve that issue with validators (something I tried) it affects the rebuilding of the DataGrid, why? After alot, and I mean alot of investigation, it appears that touching the DataGrid _or any BaseDataList descendent for that matter_ would corrupt that control, specifically when touching the DataGrid.Controls collection.
I am interested in knowing if this is a common thing, I have found a workaround that would require an article of my own, but I am still investigating if it is worth posting.
I have found a solution for all these "chain reaction" _solving 1 thing breaks another_ problems, so just let me know if interested.
Knowledge brings a greater perception of ignorance
|
|
|
|
 |
|
 |
I'm just wondering if the implementation is 100% correct,
shouldn't you first remove the existing controls from the page,
before adding the template (like beneath )?
//ADD TEMPLATE TO PAGE
this.FindControl("Form1").Controls.Clear();
this.FindControl("Form1").Controls.Add(template);
Or is it so that controls with the same Id's are overwritten
automagically by the framework ? (<asp:panel id="content" ... )
Steph
|
|
|
|
 |
|
 |
Great article. This solution is so far the simplest to implement of all templating solutions.
My problem with this approach is that each derived page must have it's own html, head, body and form tag. There's no generic control or base class to deal with this. If you were building a huge site every page would have to be changed with regard to stylesheet links etc., with a labourious find-and-replace mission.
Has anyone adapted this solution to incorporate a generic base master page/control with the html, head, body tags etc? It would be nice to be able to override the outer html on specific pages if so desired too. This would allow the derived page to literally have content only controls exactly like ASP.NET 2.
Any help would be much appreciated
Thanks ;)
|
|
|
|
 |
|
 |
What if someone changes the form name from "Form1" to something else, you should implement a generic way to do that.;)
|
|
|
|
 |
|
 |
// loop until we find the page's form
if( PageForm == null)
{
foreach(Control con in Controls)
{
if(con is System.Web.UI.HtmlControls.HtmlForm)
{
PageForm = (System.Web.UI.HtmlControls.HtmlForm) con;
break;
}
}
}
Regards,
Kalyan Krishna
|
|
|
|
 |
|
 |
i guess we can do it right in the begining . The code shows if we dont find Form1 then staring look for any.But it should look for any form .
so the process should be
"find" , not "fail and find"
Regards,
Mehfuz Hossain.
|
|
|
|
 |
|
 |
Generally , I think it is a good practice to keep just one form on a page in asp.net.
I practice this myself, so the code snippet works well for me..
Kalyan
Regards,
Kalyan Krishna
|
|
|
|
 |
|
 |
Hi,
Thanks for your article. I try it but unfortunately I can't use the FindControl methode anymore.
When I want to find a control of the page
- Either 'this.FindControl("ControlId")' can't find it and I get 'null'
- Or I use 'content.FindControl("ControlId")' and I get the exception : Multiple controls with the same ID '_ctl0' were found ...
Can some one help me ?
Thanks you very much
Pete
|
|
|
|
 |
|
 |
Sorry but now I am sure that your solution does not always work :
In your sample projet, just add a DataGrid to both WebForm1 and MasterTemplate then bind them with some data.
Therefor when you do a postback by clicking on the the calendar you get an exception.
I like your solution because it's very simple, but how can I make it works properly ?
Regards,
Pete
|
|
|
|
 |
|
 |
I try to run this masterpage application for my website, but I get an error while loading it. Can someone tell me what's go wrong here and how I can reslove this problem? I use ASP.NET 1.1 --- Parser Error Message: Could not load type 'MasterPage.Global'. Source Error:
Line 1: <%@ Application Codebehind="Global.asax.cs" Inherits="MasterPage.Global" %> --- Jan Willem Bouma
|
|
|
|
 |
|
 |
I had the same problem:
Just remove the html that got pasted by accident in the codebehind of WebForm1
(Page_Load function / WebForm1.aspx.cs )
Steph
|
|
|
|
 |
|
 |
How can I access the LabelError from the MasterPage's event handler (BasePage_Error) to set the error message so that I don't have set error's in the derived classes?
In my current BasePage I automatically propogate the errors to my BasePage's eventhandler BasePage_Error, but really liked your idea in your article and wanted it to incorporate into my BasePage that derives from the .Net framework's Page class. In my current solution I just clear the Response and set the in the BasePage error.
Marat
|
|
|
|
 |
|
 |
Someone convince my boss to let me publish something! &*#$(*! NDA!
I concocted a templated page solution about 2 years ago that I've continually refined and expanded.
It currently supports unlimited numbers of "active" areas within the template, externally modified template files, no need for placeholder controls.
We use it on all of our websites too.
And the boss won't let me publish it cuz it was written for work.
|
|
|
|
 |
|
 |
Give us contact info of ur boss n let's see wht we can do...
|
|
|
|
 |
|
 |
Why not just publish the ideas to the sollution here.
|
|
|
|
 |
|
 |
The unfortunate side-effort, if I'm seeing things right, the resulting HTML is prefixed with: <form name="Form1" method="post" action="..." id="Form1"> <input type="hidden" name="__VIEWSTATE" value="..." /> prior to any header tags (<!DOCTYPE...>, <html>, etc) which unfortunately gives some browsers angst. This appears to be the side-effect of using a master form container. Any ideas on a workaround? Mark Macaulay
|
|
|
|
 |
|
 |
In my application, the form and viewstate are always embedded in the <BODY> tag!
|
|
|
|
 |
|
 |
Does anybody know how to get at preInit in vb.net
i tried oninit
Imports System
Imports System.Web.UI
Public Class MasterPage
Inherits System.web.ui.Page
Protected Overrides Sub oninit(ByVal e As EventArgs)
' load template
Dim template As New UserControl
template.LoadControl("~/MasterPageTemplate.ascx")
If Not template Is Nothing Then Response.Write("template ok ")
' load content
Dim content As New Control
content = Me.FindControl("Content")
template.FindControl("ContentPlaceHolder").Controls.Add(content)
FindControl("Form1").Controls.Add(template)
MyBase.OnInit(e)
End Sub
End Class
But it does not find the control properly
|
|
|
|
 |
|
 |
sorry being stupid
Protected Overrides Sub onload(ByVal e As EventArgs)
' load template
Dim template As Control = LoadControl("~/MasterPageTemplate.ascx")
' load content
Dim content As Control = Me.FindControl("Content")
template.FindControl("ContentPlaceHolder").Controls.Add(content)
FindControl("Form1").Controls.Add(template)
MyBase.OnLoad(e)
End Sub
|
|
|
|
 |
|
 |
It works... Thanks... I find the IDE useless though once you build the panels... Any ideas... I know there's a workaround.
Great Article...
|
|
|
|
 |
|
 |
Thanks for sharing Yitzhak
I am working on an ASP.NET website as we speak, and was looking for a solution to master pages, and this fits the bill perfectly.
We should all share more, we know it, you know it. It's having the time to put together an article... I'll endeavour to share more myself
Regards,
Simon Hughes
|
|
|
|
 |
|
 |
Just what the doctor ordered, we are about to start a new project and what to use masterpages but can not wait for ASP.net 2 (plus SP1). Looks like we can simply switch when the time is right.
Thanks
Simon
|
|
|
|
 |
|
 |
I can confirm that the solution described is really working. And it really gives you an advantage of using a page design created once without any headache. And it is very similar to what Microsoft has in .NET Framework 2.0. We have applied the same approach when we were working on the web application DriversKnowledgeTest.com and it showed quite a good result.
When decided to go for this MasterPage solution we were thinking about two main points:
1. Do not waste time for multiple recreating and repetition of the same html code on every page,
and
2. To be ready for porting the solution to the .NET 2.0 when it is time.
Alexander Turlov
Software development consultant, MCP
|
|
|
|
 |