ASP.NET 2.0 MasterPages and FindControl()
Argh. I'm going through an older application and replacing a somewhat complex scheme of user control templating with Master Pages today. For the most part this has been going real well until I hit a page that that relies on page inheritance where there's a common page base class that needs to have access to the controls on the page.
ASP.NET has never made this exactly easy, because the base class doesn't allow you access to the controls from the lower level as ASP.NET adds the properties higher up in the hierarchy. In the past I've been working around this by adding properties for the controls to the base class and then overriding these properties, but in ASP.NET 2.0 the control definitions are auto-generate with no chance to override the control definitions. The only workaround has been using FindControl() and dynamically retrieve the control definitions.
And this is where things get a bit tricky with MasterPages. The problem is that when you use MasterPages the page hierarchy drastically changes. Where a simple this.FindControl() used to give you a control instance you now have to drill into the container hierarchy pretty deeply just to get to the content container.
So in the past I might have done this in my C# base class:
protected Label lblError = null;
protected DataGrid dgItemList = null;
protected void AssignControls()
{
this.lblError = this.FindControl("lblError") as Label;
this.dgItemList = this.FindControl("dgItemList") as DataGrid;
}
you now have to drill into the containership with code like this:
protected void AssignControls()
{
this.lblError = this.Master.FindControl("Content").FindControl("lblError") as Label;
this.dgItemList = this.Master.FindControl("Content").FindControl("dgItemList") as DataGrid;
}
This isn't so bad, except when you're trying to figure out how to get to your controls <s>.
It really seems lame that Microsoft hasn't added a recursive FindControl() method to the Control class that drills into child containers. While this certainly isn't optimal in terms of performance it sure would make life a lot easier in a lot of situations, and this surely is one of them.
Not exactly rocket science to create a method that does this:
/// <summary>
/// Finds a Control recursively. Note finds the first match and exists
/// </summary>
/// <param name="ContainerCtl"></param>
/// <param name="IdToFind"></param>
/// <returns></returns>
public static Control FindControlRecursive(Control Root, string Id)
{
if (Root.ID == Id)
return Root;
foreach (Control Ctl in Root.Controls)
{
Control FoundCtl = FindControlRecursive(Ctl, Id);
if (FoundCtl != null)
return FoundCtl;
}
return null;
}
with this the code becomes:
/// <summary>
/// Assigns controls from the subclassed control to this instance so
/// we always can access the controls in our base class.
/// </summary>
protected void AssignControls()
{
this.lblError = wwWebUtils.FindControlRecursive(this.Master,"lblError") as Label;
this.dgItemList = wwWebUtils.FindControlRecursive(this.Master, "dgItemList") as DataGrid;
}
Although this is easier, I suspect it's better to do the explicit thing if that option is available to you as it probably has better performance. Also I suspect Microsoft didn't include this sort of a function in ASP.NET natively because there's potential ambiguity here – there could be more than one control Id that matches a name.
The Voices of Reason
# re: ASP.NET 2.0 MasterPages and FindControl()
As to using protected properties for the control in the base - that doesn't work. I think that works if the properties are defined in the partial class, but not with the base class.
I have:
ItemListBase.cs (controls defined)
which is then inherited by the ASPX.cs partial classes. In there I can see the controls defined in ItemListbase.cs - in code inside of ItemListBase - is null.
So the way I work around this now is that I have a method AssignControls() that goes out and does a bunch of FindControl calls to retrieve controls and explicitly assign them.
I'm not sure why this should be so - the controls are obviously visible in the partial class higher up in the class hierarchy, so I'm not sure why they shouldn't be visible in the base class. The only thing I can defer from this is that ASP.NET creates teh new properties with the 'new' keyword so they override the base controls.
# re: ASP.NET 2.0 MasterPages and FindControl()
Try using CodeFileBaseClass in your @ Page directive. This let's the ASP.NET code generator find those protected fields in your base class and wire them to the controls in the aspx.
I wish we didn't need to use this attribute, it feels messy.
# re: ASP.NET 2.0 MasterPages and FindControl()
Still, all things considered this is cleaner than my use of a set of FindControl() calls.
# re: ASP.NET 2.0 MasterPages and FindControl()
Thanks on both counts.
Bill
# re: ASP.NET 2.0 MasterPages and FindControl()
And yes, this was part of the reason that this actually came up <g>...
# re: ASP.NET 2.0 MasterPages and FindControl()
I have a dropdownlist inside the gridview as a template column defined as follows:
<asp:TemplateField HeaderText="Choose Location">
<ItemTemplate>
<asp:DropDownList ID="ddlChooseLoc" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
I have the gridview inside of a master page- content hierarchy.
I have declared the CodeFileBaseClass in your @ Page directive; I have also declared a variable of the type dropdownlist in the base class.
When I try to access it from the partial class I am getting a null value for the dropdownlist variable.
I even tried to a FindControl on the dropdownlist still I am getting a null.
Any idea what I may be missing?
Thanks
-Siva
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
You saved me a lot of time with the FindControlRecursive advice.
Sam
# re: ASP.NET 2.0 MasterPages and FindControl()
I've looked at every MSDN ocurrance of the method as well as trolled the various .NET sites but nothing seems to solve my issue.
Anyway, I have a dropdownlist set into a panel of a UserControl. That user control is set on the main page of the IssueDetails. I use findCOntrol to find the dropdownlist (and it does) but the value isn;t captured. Any ideas? I cannot believe that the difference between 1.1 and 2.0 is so great that this simple method now fails...
Sean~
PS: I like the recursive find... a great tool if you don;t want to dig into the debug windows to find the path explicitly...:)
# re: ASP.NET 2.0 MasterPages and FindControl()
I have a dropdown in the master page that I need to repopulate my child page when the dropdown posts back. I can not get the value of the dropdown in the child page. I tried the findcontrol but does not give me a result.
# re: ASP.NET 2.0 MasterPages and FindControl()
I have a similar issue, I have been setting up the master page main content placeholder as its own variable...like thus...
Dim main As ContentPlaceHolder = CType(Master.FindControl("MainContent"), ContentPlaceHolder)
Then all other findcontrols are just main.findcontrol("yourcontrol"). If you were to setup the main content placeholder for this.Master.FindControl("Content") in your example above as its own variable, would it make drilling down quicker and easier to code, as it dosnt have to go back to find the masterpage contentplaceholder control to any find childern...?
# re: ASP.NET 2.0 MasterPages and FindControl()
That only solves part of the problem. If you have other containers inside the master container you still need to drill into that. So yes it's good to bypass a step if you know it's there, but ultimately you may still need to drill deeper to find controls.
It's always best to find controls at the right level. It's usually generic code that has to use FindControl() in the first place so in those cases you usually don't have any control over what's actually available.
# re: ASP.NET 2.0 MasterPages and FindControl()
This looks just what I am trying to resolve myself, but in VB. I have a Grid view (GridView1) contained in a master page and I am trying to store the value of the selected records key in a session control.
So I have set up
Dim MasterGridView As GridView = CType(Master.FindControl("GridView1"), GridView)
but I am still getting a System.NullReferenceException.
My Sub routine then contains NewText = MasterGridView.SelectedRow.Cells(0).Text
in order to try and store the records ID.
Any views on how this type of issue can be reolved?
# re: ASP.NET 2.0 MasterPages and FindControl()
Check the page to make sure what your container ship is. If the grid sits inside of another container - a panel or even a div with runat=server your containership stack is blown and FindControl won't find the control.
One way to see the container ship is to print the UniqueID of the control to the Web form - that'll show the names in the chain.
# re: CodeFileBaseClass
However, if you define your base class one level higher in the class hierarchy (ie. Page -> MyPageBaseClass -> MyPage1 -> MyPage2) you can't use CodeFileBaseClass to point at MyPageBaseClass. This means any truly generic Page subclass that doesn't have a visual ASPX file associated with it won't be able to see the any controls defined higher up in the tree even if the properties are defined at the base level.
# re: ASP.NET 2.0 MasterPages and FindControl()
Best
# re: ASP.NET 2.0 MasterPages and FindControl()
Great to know about it.
Keep it up.
# re: ASP.NET 2.0 MasterPages and FindControl() for dynamically created IDs
I am using a repeater to display a collection list on a content page and am using a master page. As the data is being bound to the repeater I'm attempting to dynamically generate TextBox IDs so that I can later associate the contents of each TextBox with the collection list object it's data was populated from.
((TextBox)e.Item.FindControl("txtBox")).ID = "txt_" + tempObjectList.FiscalYear.ToString();
So if the contents of the TextBox changes, I can save it back to the liste object it is associated with.
I am however having quite a time trying to access the TextBox ID after its assigned.
For example, if I set the ID = "txtbox_01" and try to access it using a find control, it breaks and gives me an "Object reference not set to an instance of an object" error. When I look at the page source, the TextBox ID is set to id="ctl00_contentBody_txt_01".
When trying to perform some action on the data in the TextBox I try to access it as follows:
((TextBox)FindControl("txt_" + tempObject.FiscalYear.ToString())).Text
Any help would be greatly appreciated!
Thanks,
Mick
# re: ASP.NET 2.0 MasterPages and FindControl()
I have a UserControl form and everything is done there. only thing I do in aspx page is to call usercontrol and pass parameters. all this worked fine till I was not using MasterPages. When I started using MP, I got error "Object not referenced..." in my code behind for aspx page. I'll do somemore testing but it seems working fine after I added recursive FindControl.
thanks bunch.
# re: ASP.NET 2.0 MasterPages and FindControl()
Here is the code snippet
1. This is the declaration in the master page (masterPage.master)
<asp:ContentPlaceHolder ID="contentID" runat="server">
</asp:ContentPlaceHolder>
2.This is the declaration in the content page (content.aspx)
<asp:Content ID="contentID" runat="Server" ContentPlaceHolderID="contentDetails">
<asp:Label ID="Label1" runat="server" Text="Fisrt Text"></asp:Label>
</asp:Content>
3. Onpageload I'm trying to change the value of Label1 to "Second Text"
I have written the below code to do so but it is doing nothing. When the page loads I see "First Text", where in I'm expecting "Second Text"
Here are the couple of approach I took
1. Find control method
In conent.aspx.cs on Page_Load event I have the below code.
ContentPlaceHolder cnt;
cnt= (ContentPlaceHolder) Page.Master.FindControl("contentDetails");
Label lbl;
lbl= (Label) FindControlRecursive(this.Master, "Label1");
lbl.Text = "Second Text";
2. I Tried setting <%@ MasterType VirtualPath="~/masterPage.master" %>
but no luck..
3. I tried FindControlRecursive()
still it doesn't work
Anyone has any idea what is going wrong here??
thanks in advance.
-sj
# re: ASP.NET 2.0 MasterPages and FindControl()
I've written code to make my content page modify my master page, no problem, but now I'm looking at trying to place a version of this code as a method in the masterpage codebehind. My thinking was that this way I wouldn't have to add the code to all of the content pages. Codebehind in the content pages could simply call the relevant method. My problem was that I couldn't get masterpage codebehind to affect controls on the masterpage - I tried various permutations of FindControl, but I couldn't get it to work - "Object reference not set to an instance of an object".
I'd have thought that referencing a control on the masterpage from the masterpage codebehind would be easier, but I haven't been able to do it...
Any thoughts welcome, apologies if this is something of newbie query.
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
Instead of iterating through the controls and do recurvise methods on the hierachy, try using the event called ItemDataBound. ItemDataBound is available on all of the Grid's (Repeater, GridView, DataGrid, etc)
The ItemDataBound gives you the ItemEventArgs for the control you are using.
I have an repeater which is placed inisde a MasterPage, in the repeater i have several Label control. So how do I find these Labels ?
Look here:
protected void rptTemplates_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Header || e.Item.ItemType == ListItemType.Footer)
{
foreach (Control ctrl in e.Item.Controls)
{
//Got ya...
}
}
}
Inside the foreach I have my labels...
# re: ASP.NET 2.0 MasterPages and FindControl()
I am generating some usercontrols (A) inside another usercontrol (B) and calling usercontrol (B) in an .aspx page that has a masterpage.
So, my aspx page calls the master page, and inside the container of the masterpage I call my usercontrol B. This usercontrol generates dynamically usercontrols of type A inside an asp:table. The asp:table is inside a View1, and the View1 is inside a Multiview1, and the Multiview1 is inside an Update Panel.
This is my html code (I should mention that control A has a checkbox, and 2 dropdownlists:
//This is usercontrol B and I register usercontrol A in this page
<%@ Register ... src="~/usercontrol_A.ascx" ... %> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:MultiView ID="MultiView1" runat="server"> <asp:View ID="View1" runat="server"> <asp:Table runat="server" ID="offeredMenusTable" Width="720px"></asp:Table> </asp:View> </asp:MultiView> </ContentTemplate> </asp:UpdatePanel>
//This is the codebehind for this page: //This creates the controls just find private void create() { TableRow trItem = new TableRow();//New <tr> TableCell tdItem = new TableCell();//New <td> TableCell tdItem2 = new TableCell();//New <td> for(int i=0; i < 5; i++) { ns.ucs.uc_A.uc_A ckBox = (ns.ucs.uc_A.uc_A)LoadControl(@"~/ns/ucs/uc_/.uc_A.ascx"); ckBox.ID = menuItemID.ToString() + "|" + i; tdItem.Controls.Add(ckBox); trItem.Cells.Add(tdItem); this.offeredMenusTable.Rows.Add(trItem); //this.offeredMenusTable.Controls.Add(trItem); I tried this, but no luck finding it either _arrlstFoodItemIDs.Add(ckBox.ID);//Adding the ckBox IDs to an ArrayList } Session["_arrlstFoodItemIDs"] = _arrlstFoodItemIDs; } //But when I try to find them the FindControl returns null void checkAll() { _arrlstFoodItemIDs = (ArrayList)Session["_arrlstFoodItemIDs"]; for (int i = 0; i < _arrlstFoodItemIDs.Count; i++) { ns.ucs.uc_A.uc_A ckBox = (ns.ucs.uc_A.uc_A)LoadControl(@"~/ns/ucs/uc_/.uc_A.ascx"); ckBox=this.FindControl(_arrlstFoodItemIDs[i].ToString()) as ns.ucs.uc_A.uc_A; //The line above returns null if(ckBox._CbBoolVal == false)//_CbBoolVal-checks the usercontrol A checkbox { ckBox._CbBoolVal = true; } } } //As I said before I generate the usercontrols (A) fine, but I can't find them. I've been working on this problem for 3 days now. So, any help is appreciated. Thank you!!!
# re: ASP.NET 2.0 MasterPages and FindControl()
cheers, dan
# re: ASP.NET 2.0 MasterPages and FindControl()
The below code is in the load event of the content page.
Usercontrol is a generic type.
Dim headerlnk As LinkButton
Dim menuCtl As UserControl
menuCtl = CType(Master.FindControl("SiteMapCtl1"), UserControl)
menuCtl.Visible = False
headerlnk = CType(Master.FindControl("lnkUnits"), LinkButton)
headerlnk.Visible = True
# re: ASP.NET 2.0 MasterPages and FindControl()
Keep in mind that many systems (mine included) don't have a timer resolution of less than about 16ms. See here:
http://www.eggheadcafe.com/articles/20021111.asp
So the fact that I am always getting 0ms results really means that it is finishing in less than 16ms. Still blazing fast, in my opinion.
But don't take my word for it; try timing it yourself. But I'm satisfied that a recursive control lookup will work fine for my purposes. I've override the Page.FindControl method with a recursive lookup for my MasterPage-enabled apps.
-Josh
# re: ASP.NET 2.0 MasterPages and FindControl()
I think Scott's point of why they didn't put it in the product makes some sense although I still would love to see an optional parameter on FindControl to do the recursive lookup, rather than having a separate function. OTOH, I suspect anything we write on our end ourselves is likely to be faster than what Microsoft writes for us since they check for every possible failure/security scenario etc. <s> which is as it should be...
# re: ASP.NET 2.0 MasterPages and FindControl()
However, I'd still say, do some benchmarking before you say "it will work fine" or "it will be too slow." In my case I think it's going to work great. Let's say that it does add 12ms per lookup -- that means doing 5 lookups would cost me 60ms. Looking at the trace output for one of the forms I'm working on right now, i can see that total page generation time is about 900ms. That's about a 7% performance difference one way or the other. To me, that's acceptable. To others, maybe not.
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
How can i access the method wriiten in the Content Place Holder ASPX page from master page as the ASPX page gets loaded first than the Master Page load event?
Parimal
# re: ASP.NET 2.0 MasterPages and FindControl()
You can always get access to the page through this.Page() in the master and then casting to your sepcific page type.
# re: ASP.NET 2.0 MasterPages and FindControl()
Thanks for the reply. I have a tab strip in Master Page and a Main ASPX page in COntent Place holder. We want to dynamically load the User Controls in the Panel in ASPX page when tab items are clicked. But the Problem is that ASPX page load event gets fired before Master Page events. SO ASPX page dont get what tab is clicked. So we want to access the ASPX page method for loading the USer control in the TAB click event of master page.
How to resolve these issue?
Thanks in Advance,
Parimal
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
I though, this is a bug, that the following code not work.
Control ctrl = this.FindControl("control");
thx ben
# re: ASP.NET 2.0 MasterPages and FindControl()
Create a base class which inherits Page
Public Class DashBoardPage
Inherits System.Web.UI.Page
Then write a function in base class ....
Protected Overloads Function FindControl(ByVal id As String) As System.Web.UI.Control
Return Page.Master.FindControl("cphForm").FindControl(id)
End Function
Now use it in Partial class. (cphForm = Your main content area id on master page )
# re: ASP.NET 2.0 MasterPages and FindControl()
this.Master.FindControl("Content$lblError") as Label;
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
As for needing to recurse, the control can exist anywhere on the content page (even as a sub control), so the need to recurse is removed.
The only case where I could see you having an issue is if you have a master page within a master page, but since the designer doesn't support that I doubt anyone would hit that sort of issue).
To use your assign controls example. The only real change is the removing of the second FindControl :
protected void AssignControls() { this.lblError = this.Master.FindControl("Content$lblError") as Label; this.dgItemList = this.Master.FindControl("Content$dgItemList") as DataGrid; }
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
The recursive deal is useful in situations and required when you don't know the control path and you need to find a control. This is a common scenario in generic control development when one control interacts with others on the page.
# re: ASP.NET 2.0 MasterPages and FindControl()
Vishal Khanna
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
Thanks.
# re: ASP.NET 2.0 MasterPages and FindControl()
I have a similar setup where I have a hierarchy of classes in my pages. I have a base page class, a site page class, a forum page class, and a page type class. The base page class implements application logic. The site page class implements functionality unique to the site, as the application runs on several sites. The forum page class implements functionality specific to forums (areas), and the page type class implements specific page type functionality (Contact Us Page, Discussion Page, Chat Page, etc.)
I needed for the base page class to have access to several controls on the page, and I didn't want to make several calls to FindControl as I assumed the performance would be terrible. What I did was register control names in the Page.Init. Effectively, I built a collection/array of control names. Any of the page classes in the hierarchy could add to this array. Effectively, they were saying "I'm going to need access to control xyzzy. Please find it for me." Then, in the base page class's load method, I manually traversed the page's control tree. Each time I found a control name that matched one that had been registered, I added a reference in another collection to that control. MyPageControls("xyzzy") = Object. After this routine ran, each of the page classes could access the controls they needed via the collection.
I still wasn't overly fond of this, but it seemed much more efficient than calling Page.FindControl 30 or 40 times.
Eventually, I added a prefix to control names that needed to be identified. This way I was a little more efficient in the code. I could then say "If left(Control.ID,4)="XYZ_" then MyPageControls.Add(Control.ID,Control)". This seemed a bit more efficient since I didn't have to traverse/search a collection of control names for each control I found.
NOW, I find this! (Thank you Google for bringing this page up when I searched on "asp.net findcontrol performance".)
It seems that performance would benefit from using the "CodeFileBaseClass" directive.
Thanks! (And I hope I didn't miss something by not reading all of the posts!)
# re: ASP.NET 2.0 MasterPages and FindControl()
Rick Strahl (7/2/06) pegged it. If you have a deeper page hierarchy, you're screwed on that whole CodeFileBaseClass solution.
Guess I'll stick with my existing solution.
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
I recently got into a problem in finding a TextBox inside a Repeater control in a MasterPage environment and I finally got the solution with the following code:
this.Repeater1.DataSource = ds; // ds is some data source this.Repeater1.DataBind(); // Bind the Repeater1 with the data source // Locate the TextBox control in a MasterPage environment // i is the row number where TextBox is located inside the Repeater TextBox tb = this.Master.FindControl("ContentPlaceHolder1").FindControl("Repeater1").Controls[i].FindControl("MyTextBox") as TextBox;
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
I kept encountering this error: System.NullReferenceException "Object reference not set to an instance of an object". However, when I did a Watch I was able to see the previous page's controls (with their values), and that left me scratching my head.
<b>Here's my old code</b>
using System;
using System.Configuration;
using System.Collections;
using System.Data;
using System.IO;
using System.Security.AccessControl;
using System.Security.Permissions;
using System.Security.Principal;
using System.Security;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class PODResults : System.Web.UI.Page
{
private DatabaseManager DBM = new DatabaseManager();
protected DataTable resultDT = new DataTable();
private Int16 rowCt = 0;
private Int64 executionTime = 0;
private string criteria = "";
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
try
{
string pagename = "";
if (PreviousPage != null && PreviousPage.IsCrossPagePostBack)
{
pagename = PreviousPage.ToString();
criteria = ((TextBox)PreviousPage.FindControl("txtCriteria")).Text;
resultDT = DBM.PODiscrepancy(criteria);
resultDT.AcceptChanges();
rowCt = (Int16)resultDT.Rows.Count;
}
if (rowCt == 0)
{ /* Let user know that there were no results.
disable the buttons on the search results
*/
BtnExcel.Visible = false;
//BtnClr.Visible = false;
//msg_Lbl.Text = "No Records Found";
//msg_Lbl.ForeColor = System.Drawing.Color.Red;
} //end if
} //end try
catch (Exception ex)
{
Console.WriteLine("Application caught exception. Exception found at {0}", ex.StackTrace);
}
finally
{
Session["PODRequestEnd"] = System.DateTime.Now;
Session["PODExecutionTime"] = (System.DateTime.Now.Ticks - ((DateTime)Session["PODRequestStart"]).Ticks) / 600000000; //convert ticks to minutes 1 minute = 600,000,000 ticks
executionTime = (Int64)Session["PODExecutionTime"];
rowCt = (Int16)resultDT.Rows.Count;
if (rowCt > 0)
{
//Finally, I can begin to work with the data set.
Session["PODResultsDataTable"] = resultDT;
rptPODResults.DataSource = resultDT;
rptPODResults.DataBind();
OnExportGridToCSV();
//Response.Write("finally");
}
}//end finally
} //end if
else
{ // IsPostBack
//Finally, I can begin to work with the data set.
resultDT = (DataTable)Session["PODResultsDataTable"];
rowCt = (Int16)resultDT.Rows.Count;
rptPODResults.DataSource = resultDT;
rptPODResults.DataBind();
//Response.Write("finally");
}
return;
} //Page_Load()
public void BtnExcel_Click(object sender, System.EventArgs e)
{ //or I can use the same exact code that I used to create the CSV file and put a ".xls" extension on the filename.
try
{
if (rowCt > 0)
{
DataGrid myDataGrid = new DataGrid();
myDataGrid.DataSource = resultDT;
myDataGrid.DataBind();
Response.Clear();
Response.AddHeader("content-disposition", "attachment;filename=" + Convert.ToString(DateTime.Now.ToString()) + "_PODiscrepancyResults.xls");
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/vnd.ms-excel";
System.IO.StringWriter stringWrite = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
myDataGrid.Controls.Clear();
myDataGrid.RenderControl(htmlWrite);//Tell the datagrid to render itself to our htmltextwriter
Response.Write(stringWrite);
//Response.End();
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
else
Response.Write("Error not caught: Zero Rows To Display!");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Response.Write(ex.Message);
}
return;
}//BtnExcel
private void OnExportGridToCSV()
{
//string currentUser = WindowsIdentity.GetCurrent().Name.ToString();
//DirectorySecurity ds = Directory.GetAccessControl(Server.MapPath("~/OutputFiles/"));
//AuthorizationRuleCollection arc = ds.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
//string sas = WindowsIdentity.GetCurrent().Groups.ToString();
//string pUser = Page.User.Identity.Name;
//string wUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
//string currentPrincipal = System.Threading.Thread.CurrentPrincipal.Identity.Name;
try
{
if (rowCt > 0)
{
// Create the CSV file to which grid data will be exported.
string fileName = DateTime.Now.ToShortDateString() + "_PODiscrepancyResults.csv";
fileName = fileName.Replace("/", "");
string fileNameAndPath = Server.MapPath("~/OutputFiles/") + fileName;
//StreamWriter sw = new StreamWriter(Server.MapPath("~/OutputFiles/"+fileName), false);
int iColCount = resultDT.Columns.Count;
if (File.Exists(fileNameAndPath))
{
File.Delete(fileNameAndPath);
}
StreamWriter sw = File.CreateText(fileNameAndPath);
// First we will write the headers.
for (int i = 0; i < iColCount; i++)
{
// Can pick out the specific columns. Do not write all the data that's in the GRID.not useful to user
sw.Write(resultDT.Columns[i].ColumnName);
if (i < iColCount - 1)
{
sw.Write(",");
}
}
sw.Write(sw.NewLine);
// Now write all the rows.
foreach (DataRow dr in resultDT.Rows)
{
for (int i = 0; i < iColCount; i++)
{
//pick out the specific columns. Do not write all the data that's in the GRID.not useful to user
if (!Convert.IsDBNull(dr[i]))
{
sw.Write((string)dr[i]);
}
if (i < iColCount - 1)
{
sw.Write(",");
}
}
sw.Write(sw.NewLine);
}
sw.Close();
} // if (resultDT.Rows.Count > 0)
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}//end ExportGridToCSV
}
<div style="background-color:blue; width:100%;height:20px;"> </div>
<b>Here is my new code</b>
--------------------------------------------------------
using System;
using System.Configuration;
using System.Collections;
using System.Data;
using System.IO;
using System.Security.AccessControl;
using System.Security.Permissions;
using System.Security.Principal;
using System.Security;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class PODResults : System.Web.UI.Page
{
private DatabaseManager DBM = new DatabaseManager();
protected DataTable resultDT = new DataTable();
private Int16 rowCt = 0;
private Int64 executionTime = 0;
protected string criteria = "";
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
try
{
string pagename = "";
if (PreviousPage != null && PreviousPage.IsCrossPagePostBack)
{
criteria = ((TextBox)PreviousPage.Master.FindControl("content").FindControl("txtCriteria")).Text;
criteria = ((TextBox)PreviousPage.FindControl("txtCriteria")).Text;
resultDT = DBM.PODiscrepancy(criteria);
resultDT.AcceptChanges();
rowCt = (Int16)resultDT.Rows.Count;
}
if (rowCt == 0)
{ /* Let user know that there were no results.
disable the buttons on the search results
*/
BtnExcel.Visible = false;
//BtnClr.Visible = false;
//msg_Lbl.Text = "No Records Found";
//msg_Lbl.ForeColor = System.Drawing.Color.Red;
} //end if
} //end try
catch (Exception ex)
{
Console.WriteLine("Application caught exception. Exception found at {0}", ex.StackTrace);
}
finally
{
Session["PODRequestEnd"] = System.DateTime.Now;
Session["PODExecutionTime"] = (System.DateTime.Now.Ticks - ((DateTime)Session["PODRequestStart"]).Ticks) / 600000000; //convert ticks to minutes 1 minute = 600,000,000 ticks
executionTime = (Int64)Session["PODExecutionTime"];
rowCt = (Int16)resultDT.Rows.Count;
if (rowCt > 0)
{
//Finally, I can begin to work with the data set.
Session["PODResultsDataTable"] = resultDT;
rptPODResults.DataSource = resultDT;
rptPODResults.DataBind();
OnExportGridToCSV();
//Response.Write("finally");
}
}//end finally
} //end if
else
{ // IsPostBack
//Finally, I can begin to work with the data set.
resultDT = (DataTable)Session["PODResultsDataTable"];
rowCt = (Int16)resultDT.Rows.Count;
rptPODResults.DataSource = resultDT;
rptPODResults.DataBind();
//Response.Write("finally");
}
return;
} //Page_Load()
public void BtnExcel_Click(object sender, System.EventArgs e)
{ //or I can use the same exact code that I used to create the CSV file and put a ".xls" extension on the filename.
try
{
if (rowCt > 0)
{
DataGrid myDataGrid = new DataGrid();
myDataGrid.DataSource = resultDT;
myDataGrid.DataBind();
Response.Clear();
Response.AddHeader("content-disposition", "attachment;filename=" + Convert.ToString(DateTime.Now.ToString()) + "_PODiscrepancyResults.xls");
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/vnd.ms-excel";
System.IO.StringWriter stringWrite = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
myDataGrid.Controls.Clear();
myDataGrid.RenderControl(htmlWrite);//Tell the datagrid to render itself to our htmltextwriter
Response.Write(stringWrite);
//Response.End();
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
else
Response.Write("Error not caught: Zero Rows To Display!");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Response.Write(ex.Message);
}
return;
}//BtnExcel
private void OnExportGridToCSV()
{
//string currentUser = WindowsIdentity.GetCurrent().Name.ToString();
//DirectorySecurity ds = Directory.GetAccessControl(Server.MapPath("~/OutputFiles/"));
//AuthorizationRuleCollection arc = ds.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
//string sas = WindowsIdentity.GetCurrent().Groups.ToString();
//string pUser = Page.User.Identity.Name;
//string wUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
//string currentPrincipal = System.Threading.Thread.CurrentPrincipal.Identity.Name;
try
{
if (rowCt > 0)
{
// Create the CSV file to which grid data will be exported.
string fileName = DateTime.Now.ToShortDateString() + "_PODiscrepancyResults.csv";
fileName = fileName.Replace("/", "");
string fileNameAndPath = Server.MapPath("~/OutputFiles/") + fileName;
//StreamWriter sw = new StreamWriter(Server.MapPath("~/OutputFiles/"+fileName), false);
int iColCount = resultDT.Columns.Count;
if (File.Exists(fileNameAndPath))
{
File.Delete(fileNameAndPath);
}
StreamWriter sw = File.CreateText(fileNameAndPath);
// First we will write the headers.
for (int i = 0; i < iColCount; i++)
{
// Can pick out the specific columns. Do not write all the data that's in the GRID.not useful to user
sw.Write(resultDT.Columns[i].ColumnName);
if (i < iColCount - 1)
{
sw.Write(",");
}
}
sw.Write(sw.NewLine);
// Now write all the rows.
foreach (DataRow dr in resultDT.Rows)
{
for (int i = 0; i < iColCount; i++)
{
//pick out the specific columns. Do not write all the data that's in the GRID.not useful to user
if (!Convert.IsDBNull(dr[i]))
{
sw.Write((string)dr[i]);
}
if (i < iColCount - 1)
{
sw.Write(",");
}
}
sw.Write(sw.NewLine);
}
sw.Close();
} // if (resultDT.Rows.Count > 0)
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}//end ExportGridToCSV
}
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
how to make the subdomain folder in web application by using asp.net and copy all files which are present in a particular domain.
Just example -->
www.ibloz.com website domain have some files and folder in wwwroot folder.I wanna to copy all files in this domain as a individual folder for a particular user.If a user name
is anuj then webite as a called by url www.anujibloz.com.
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
I'm still amazed by the amount of time that myself and other developers waste on finding answers to issues like this in order to achieve something incredibly simple. eg. I just want to get the text value submitted in a text box.
I thought that .Net was supposed to make developer's lives easier. With classic ASP we knew that we could get the value of any form element with request.form("element_name") and it worked regardless of any template etc design.
Classic ASP: request.form("element_name")
ASP.Net: this.lblError = this.Master.FindControl("Content").FindControl("element_name") as Label;
Progress? I think not.
# re: ASP.NET 2.0 MasterPages and FindControl()
If you want simple - keep it simple. Don't use master pages, don't use the high level abstractions and you get the same behavior. if you want to take advantage of the high level features then you have to play by the rules of the framework.
# re: ASP.NET 2.0 MasterPages and FindControl()
GBN
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
Master -> PlaceHolder -> ControlHolder -> User control -> GridView.SelectedValue ---> NULL
the funny thing is that I can see the
GridView.SelectedValue
GridView.SelectedIndex
GridView.SelectedKey.Value
from the watch panel, everything has got the value
but.... it throws NULL Object.....
btw, i was trying to do some work at Pre-Render
# re: ASP.NET 2.0 MasterPages and FindControl()
<Content>
<ListView>
<LayoutTemplate>
<DataPager />
</LayoutTemplate>
<ItemTemplate>
<TabContainer>
<TabPanel>
<Label ID="lblHx" Text='<%# Eval("Hx")%>' />
</TabPanel>
<TabPanel>
<Label ID="lblExam" Text='<%# Eval("Exam")%>' />
</TabPanel>
...
</TabContainer>
</ItemTemplate>
<EditItemTemplate>
<TabContainer>
<TabPanel>
<TextBox ID="txtHx" Text='<%# Bind("Hx")%>' />
</TabPanel>
<Tabpanel>
<TextBox ID="txtExam" Text='<%# Bind("Exam")%>' />
</TabPanel>
...
</TabContainer>
</ListView>
<ObjectDataSource />
</Content>
The object that is passed to my update method is not picking up the values entered by the user in the page's Web controls.
Do I need to handle the Updating event of ListView and there use your FindControlRecursive method to reference the controls inside the AJAXControlToolkit.Tabcontainer control to manually fill the object being passed to my update method?
For the sake of simplicity, the following omits any reference to the object being passed and shows how to get the text from a control inside one of the tabpanels using your method. My question is, Is this the only (or best) way to get the values I need for my object, which really defeats the idea of using an object at all since you need to manually set the value of each property?
protected void lvOpenVisits_ItemUpdating(object sender, ListViewUpdateEventArgs e)
{
ListView lv = sender as ListView;
TextBox hx = FindControlRecursive(lv, "txtHx") as TextBox;
string txt = hx.Text;
}
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
I used this.Page instead for a reference in my case though.
Again, thanks!
/Jonas
# re: ASP.NET 2.0 MasterPages and FindControl()
So I started tinkering with them in a test website. And surely, in a Page_Load of page that inherited from a master file, I could reference a control using a member variable like
Label lbl1 = lblName; //lblName exists on the aspx
but in the very next line,
Label lbl2 = (Label)Page.FindControl("lblName");Nor did
Label lbl3 = (Label)Page.FindControl("ctl00_ContentPlaceHolder1_lblName");
//ctl00_ContentPlaceHolder1_lblName being the clientID of the rendered Label ctrlAlso,
Content ct = (Content)Page.FindControl("Content1"); //did not yield anything
nor using
Page.Master.FindControl instead of Page.FindControl in any of the statements above was any good.
So, I'm wondering if the solution suggested by Scott Allen
(
Rick:
Try using CodeFileBaseClass in your @ Page directive. This let's the ASP.NET code generator find those protected fields in your base class and wire them to the controls in the aspx.
)
is a conclusive solution to this problem if we declare the control names as protected fields in the base class like he suggested.
Some others have suggested using the PreviousPageType directive on your page like
<%@ PreviousPageType VirtualPath="~/Page1.aspx" %>
and exposing what you need to access from the previous page as a public property.
In my application, I have several pages that can post to an "update.aspx" page, which then uses Page.PreviousPage.FindControl to find values in hidden fields from the previous page... Any suggestions on how I would do this if I used Masterpages...?
Incase Scott is reading this, I really enjoy your articles too. Whats your take on this?
How would you guys say I can recursively go through all the content controls on a page inheriting from a master page to just see all the controls, their parents and children just for experimentation sake...to see how the master and content pages are merged together?
Thanks again guys!
Ghazanfar
# re: ASP.NET 2.0 MasterPages and FindControl()
protected void btnSubmit_Click(object sender, EventArgs e)
{
ContentPlaceHolder cph = (ContentPlaceHolder)Master.FindControl("ContentPlaceHolder1");
Label lbl0 = (Label)cph.FindControl("lblName");
TextBox txb1 = (TextBox)cph.FindControl("txbName");
DropDownList gen = (DropDownList)cph.FindControl("ddlGender");
lblResult.Text = lbl0.Text.ToString() + txb1.Text.ToString() + "<br>Gender: " +
gen.SelectedItem.ToString();
}
I realise that you (Rick or Scott) know this all too well, I thought I'd post for the benefit of other readers:)
Still, any suggestions on "how to think" to be able to percieve the hierarchy of the controls on the final rendered HTML..
I was also wondering, when a web request is sent to a server for a page that inherits from a master page, the server does the merge, generates the html and sends that to the clients browser, correct? Everytime this client posts back to the server, say, to do some operation on some user input on the same page, should it address the controls with their "new" IDs
eg. ConvertToInt32(ctl00_ContentPlaceHolder1_txb1.Text) +
ConvertToInt32(ctl00_ContentPlaceHolder1_txb2.Text);
or simply:
ConvertToInt32(txb1.Text) + ConvertToInt32(txb2.Text)
I realize we should never hardcode the ctl00_ContentPlaceHolder1_ part into our applications, but just wondering which of these two would be recognized? Still having a hard time grasping how the nuts & bolts of a masterpage driven page works...:(
# re: ASP.NET 2.0 MasterPages and FindControl()
For i = 0 To j
Dim MyTextBox As New TextBox
MyTextBox.ID = "TextInBrief" & i
MyTextBox.TextMode = TextBoxMode.MultiLine
MyTextBox.Height = 88
MyTextBox.Width = 443
MyTextBox.Text = "TextInBrief" & i
Panel1.Controls.Add(MyTextBox)
Dim MyLiteral2 As New LiteralControl
MyLiteral2.Text = "<br/>"
Panel1.Controls.Add(MyLiteral2)
next
But when i try to retrieve the values of texboxes by clicking button1 got err:Object reference not set to an instance of an object. I have used masterpage.
button click code follows
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs)handles Button1.Click
Dim brf As String = ""
Dim i As Int16 = 0
For i = 0 To 4
Dim txt As TextBox = CType(Master.FindControl("ContentPlaceHolder1").FindControl("TextInBrief" & i), TextBox)
If Trim(txt.Text) <> "" Then
brf = brf & txt.Text
End If
Next
label1.text=brf
end sub
the same code i used with other my project running perfectly.
But this i don't know.
Where i made mistake? Please help me.
# re: ASP.NET 2.0 MasterPages and FindControl()
Hello,
I used your function FindControlRecursive. :)
You saved my some time.
Bye
# re: ASP.NET 2.0 MasterPages and FindControl()
Many Thanks, FindRecursive work wonderfull. I have one litle problem with one multi UC.
MasterPage(Uc1( Uc2))
FindRecursive works fine when I search Textboxes, Dropdowns in UC1 and UC2, but I not able to found one control selected inside one "Panel" used in one UC2
UC2 ( return one ItextControl --> textControl)
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="loc3_city.ascx.cs" Inherits="loc_city" %> <asp:TextBox ID="LinkCity" runat="server" Visible="false" width="30px"></asp:TextBox> <asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server"> </asp:ScriptManagerProxy> <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="conditional"> <ContentTemplate> <asp:Panel ID="Panel1" runat="server" Width="100px" Style="Display:inline"> </asp:Panel> </ContentTemplate> </asp:UpdatePanel>
UC1
<li>
<com:MultiCombo ID="City" runat="server" />
</li>
UC1 inside MasterPage.
The UC2 return one Panel with the Cities to be selected. I can cast directly in UC1 when I use DrpdownBox and selected item, but Panel not cast!
This is the Html of the zone generated
<div id="ctl00_ContentPlaceHolder1_controlPanel_ctl00_ctl00_editMetaFields_ctl00_City_Panel1" style="width: 100px; display: inline;">
<div>
<select name="ctl00$ContentPlaceHolder1$controlPanel$ctl00$ctl00$editMetaFields$ctl00$City$ctl02">
<option value="1" selected="selected">NY</option>
<option value="2">LA</option>
</select>
</div>
</div>
Any sugestion?
# re: ASP.NET 2.0 MasterPages and FindControl()
It's kind of like the jQuery Selector version for WebControls on the server ... ;)
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
Thanks Rick
# re: ASP.NET 2.0 MasterPages and FindControl()
If you want to get it by traversing a child collection, simply throw in a simple LINQ extension method called All that will recursively decend any Control collection and you have yourself a neat selection mechanism:
For example:
MyPanel.Controls.All().OfType<Panel>().FirstOrDefault()
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
I also pointed out this fact since very few (anybody?) has written anything about it. I myself discovered it while using Reflector.
Of course we agree that such a function is useful in some cases and that's why I provide the case that a useful LINQ extension is easier:
public static IEnumerable<Control> All(this ControlCollection controls) { foreach (Control control in controls) { foreach (var grandchild in control.Controls.All()) yield return grandchild; yield return control; } }
# re: ASP.NET 2.0 MasterPages and FindControl()
String ET = Request["EventTitle"].text; (All this does is give me the value that was originally there not what it was changed to)
<asp:TextBox ID="EventLink" runat="server"></asp:TextBox>
tried this in the code behind:
string EventTitle = Request["EventTitle"]; (using this I get a null)
I tried using the FindControl but that seems a bit comberson to get a value in the code behind. Every example I find is far different from eachother. I think there is something missing.
Any thoughts?
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
Your blogs are really helpful. You saved me a lot of time.
Keep Writing!!! :)
# re: ASP.NET 2.0 MasterPages and FindControl()
Thank you very much Rick. I've been looking this for hours.
And it works. Thanks again :)
# re: ASP.NET 2.0 MasterPages and FindControl()
After banging my head against the wall (literally) for 3 days, I finally came across this post and IT WORKS!!!!
Thank you so much for sharing!
# re: ASP.NET 2.0 MasterPages and FindControl()
ctl00_ContentPlaceHolder1_Wizard1_UserControl1_dlPubByGenre_ctl01_ddlAddGenre,
ctl00_ContentPlaceHolder1_Wizard1_UserControl1_dlPubByGenre_ctl02_ddlAddGenre.
When I loop through the items it only returns data for this one: "ctl00_ContentPlaceHolder1_Wizard1_UserControl1_dlPubByGenre_ctl00_ddlAddGenre"
Please any help would be much appreciated.
pubgenredatalist = Me.UserControl1.FindControl("dlPubByGenre")
Dim count As Integer = pubgenredatalist.Items.Count
Dim i As Integer
Dim dlitem As DataListItem
Dim myTable As New DataTable
myTable.Columns.Add("Pub Id", Type.GetType("System.String"))
myTable.Columns.Add("Pub Name", Type.GetType("System.String"))
myTable.Columns.Add("Genre Id", Type.GetType("System.String"))
myTable.Columns.Add("Genre Name", Type.GetType("System.String"))
For Each dlitem In pubgenredatalist.Items
Dim Genredropdownlist As DropDownList = TryCast(wwWebUtils.FindControlRecursive(pubgenredatalist, "ddlAddGenre"), DropDownList)
Dim PublicationLabelId As Label = TryCast(wwWebUtils.FindControlRecursive(pubgenredatalist, "lblpubid"), Label)
Dim PublicationLabelName As Label = TryCast(wwWebUtils.FindControlRecursive(pubgenredatalist, "lblpubname"), Label)
Dim myrow As DataRow
myrow = myTable.NewRow
myrow("Pub Id") = CInt(PublicationLabelId.Text)
myrow("Pub Name") = PublicationLabelName.Text
myrow("Genre Id") = CInt(Genredropdownlist.SelectedValue)
myrow("Genre Name") = Genredropdownlist.SelectedItem.Text
Next
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
Inside the content page, MyTest, I have a text box control txtTestControl.
In the MyTest.aspx.cs, I am trying to assign a string value to the text property of the text box control.
Depending on what value is populated in the textbox, in the MyTest.aspx page, I am trying to
extract the value using the document.getElementByID().value in a java script function.
My problem is, if I hardcode the value in the Text Property of the textbox, I can extract it from MyTest.aspx page
But if I assign value like txtTestControl.Text = "abc" in the page load, it returns blank or null.
How do I assign value to the text property of a textbox control inside a content page?
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
# re: ASP.NET 2.0 MasterPages and FindControl()
Thanks a lot...and keep up the good work....
# re: ASP.NET 2.0 MasterPages and FindControl()
A good approach to solving the performance:
MasterPage:
...
<asp:ContentPlaceHolder id="cphMain" runat="server" />
...
Code of MasterPage:
...
public Control GetControl(string ID)
{
return cphMain.FindControl(ID);
}
....
A Page:
...
<%@ MasterType VirtualPath="~/MasterPage.master"%>
...
Code of Page:
...
this.lblError = Master.GetControl("lblError") as Label;
// insted of less performance
this.lblError = this.Master.FindControl("cphMain").FindControl("lblError") as Label;
# re: ASP.NET 2.0 MasterPages and FindControl()
Thank you!
# re: ASP.NET 2.0 MasterPages and FindControl()
Summary: I am using a basically Masterpage / Content Page where I have a gridview bound to a sql table containing some rows of data firstname, lastname, state, etc. I enabled the option to delete, select, edit a row. Converted the CommandField to a TemplateFields.
When I click the Delete button for a specified row I am first firing RowDeleting method so I can grab the firstName value from the selected row and displaying the value to a label control.
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
Label FirstName = (Label)Page.FindControlRecursive("Label1");
Label3.Text = FirstName.Text;
}
The correct record deletes but the FirstName Label from the RowDeleting method always returns the Firstname for the first record in the table. Why isn't (Label)Page.FindControlRecursive("Label1") retrieving the Firstname value for the row I clicked the delete button from?
During troubleshooting I set up this method
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
Label FirstName = (Label)Page.FindControlRecursive("Label1");
Label2.Text = FirstName.Text;
}
Anytime I would click the Select button next to any row in my GV I would get the same result as above. (The FirstName) of the First Row.)
What am I missing or not understanding here?
# re: ASP.NET 2.0 MasterPages and FindControl()
this.ContentPlaceHolderGridView.FindControl("GridViewManageList") as GridView;
instead of going to the master and search for the content, you can access it directly.
# re: ASP.NET 2.0 MasterPages and FindControl()
If anyone was really concerned about performance they wouldn't be using Webforms.
# re: ASP.NET 2.0 MasterPages and FindControl()
All in all the perf difference between the various ASP.NET platforms is relatively small either way though although I totally agree - if you use WebForms the way that most tutorials teach you and using massive third party controls you're quite likely to build a dog of an application. Same is true of other platforms though.
In short, don't spout unsubstantiated crap like that that is totally subjective and dependent on what you actually do in the specific application.
# re: ASP.NET 2.0 MasterPages and FindControl()
If Not (Root.ID Is Nothing) AndAlso Root.ID.ToUpper = Id.ToUpper Then Return Root
For Each Ctl As Control In Root.Controls
Dim FoundCtl As Control = FindControlRecursive(Ctl, Id)
If Not (FoundCtl Is Nothing) Then Return FoundCtl
Next
Return Nothing
End Function
# re: ASP.NET 2.0 MasterPages and FindControl()
Going back to your problem above, you should be able to just declare the control names as protected fields on your base class -- ASP.NET 2.0 wires these up just like V1.1 does (if a page has a base class and it has the controls already declared, then it doesn't re-generate them on any sub-class).
Hope this helps,
Scott