ASP.NET cant access datatable created in Page load from inline coding - asp.net

In my Page_Load event of codebehind file, I am loading data in to a datatable.In my .aspx page I am having some inline coding,I want to display some data from this datatable.But when i am running the program,It is showing an error like "Error 64 Use of unassigned local variable 'dtblChild' "
dtblChild is my DataTable Object
Is Page_Load in codebehind executes after loading the form elements ?

Inline Code executes during the Render stage.
in the lifecycle of a page, Render happens much later than Load

Yes, the page load executes after all of the server controls have been loaded into memory, but you have to ensure that the datatable is repopulated on each refresh if you're going to use it.
I think your question indicates some deeper problems with the way you're binding to the page.
Can you post some code?

Try using a repeater control or datagridview rather than <% %> bee stings for this. Too much inline-code doesn't mix very well with code behind files: you can get unexpected results. It can work if you really know what you're doing, but you have to be careful and I wouldn't recommend it for anyone new to ASP.Net.
I also recommend that you take some time and become very familiar with the ASP.Net Page Lifecycle.

This is my inline coding
</tr>
<%
foreach (DataRow dr in dtblChild.Rows)
{
%>
<tr><td>Thissss</td></tr>
<%
}
%>
in my code behind Page_Load ,i am populating Data to a DataTable object (dtblChild)

The more "ASP.Net-ish" way to do this is like this:
<asp:Repeater ID="MyRepeater" runat="server" DataSource="dtblChild">
<ItemTemplate>
<tr><td>Thisss</td></tr>
</ItemTemplate>
</asp:Repeater>
You probably also need to declare an ObjectDatasource to wrap your datatable to make it compatible with the repeater.

Bind your dtblChild to a repeater (or DataGrid) as suggested above. It will be easier to maintain. Then populate the DataTable in a separate function and bind it to the repeater. Call that function in Page_Load when you need to.
<table>
<asp:Repeater ID="rptSearchResults" runat="server">
<ItemTemplate>
<tr>
<td><%#DataBinder.Eval(Container.DataItem, "ColumnName") %></td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
function LoadData()
{
rptSearchResults.DataSource = dtblChild;
rptSearchResults.DataBind();
}

Related

Two-way data binding of controls in a user control nested inside a FormView doesn't work

I'm trying to perform two-way data binding on the controls in my user control, which is hosted inside a FormView template:
<asp:ObjectDataSource runat="server" ID="ObjectDataSource"
TypeName="WebApplication1.Data" SelectMethod="GetItem" UpdateMethod="UpdateItem">
</asp:ObjectDataSource>
<asp:FormView runat="server" ID="FormView" DataSourceID="ObjectDataSource">
<ItemTemplate>
<uc:WebUserControl1 runat="server"></uc:WebUserControl1>
</ItemTemplate>
<EditItemTemplate>
<uc:WebUserControl1 runat="server"></uc:WebUserControl1>
</EditItemTemplate>
</asp:FormView>
The web user control:
<%# Control Language="C#" ... %>
<asp:TextBox runat="server" ID="TitleTextBox" Text='<%# Bind("Title") %>'>
</asp:TextBox>
The binding works fine when the FormView is in View mode but when I switch to Edit mode, upon calling UpdateItem on the FormView, the bindings are lost. I know this because the FormView tries to call an update method on the ObjectDataSource that does not have an argument called 'Title'.
I tried to solve this by implementing IBindableTemplate to load the controls that are inside my user control, directly into the templates (as if I had entered them declaratively). However, when calling UpdateItem in edit mode, the container that gets passed into the ExtractValues method of the template, does not contain the TextBox anymore. It did in view mode!
I have found some questions on SO that relate to this problem but they are rather dated and they don't provide any answers that helped me solve this problem.
How do you think I could solve this problem? It seems to be such a simple requirement but apparently it's anything but that...
My current workaround for this is, although rather cumbersome, to subclass the FormView class and use subclassed controls in it, implementing my own data binding logic (taking the data field name from a new property) instead of using the <%# %> syntax. Apparently, the code the latter generates is the real culprit here as it doesn't support this nested control scenario.
I ended up, using old asp include statement
<--%include file = "filename" -->
instead of using user controls for dealing with the code duplication issue.

Why is the ASP.NET Repeater.Items collection empty, when controls are on the screen?

I have an ASP page with the following repeater:
<asp:Repeater runat="server" ID="RegionRepeater"
DataSourceID="SqlDataSourceRegions" EnableViewState="true">
<ItemTemplate>
<tr>
<td valign="top">
<b><%#Eval("description")%></b>
<asp:HiddenField runat="server" ID="RegionID"
Value='<%#Eval("region_id")%>'/>
</td>
<td>
<asp:FileUpload ID="FileUpload" runat="server" Width="368px" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
(The repeater is inside a Wizard, inside a content pane).
The code behind is connected to the
protected void Wizard1_NextButtonClick(object sender, WizardNavigationEventArgs e)
event. There are two items on the screen (two rows inside the table). However, when the code tries to read those items, the Items collection is empty!
foreach(RepeaterItem region in RegionRepeater.Items)
{
// Never runs - the RegionRepeater.Items.Count = 0
FileUpload fileUpload = (FileUpload) region.FindControl("FileUpload");
String regionID = ((HiddenField)region.FindControl("RegionID")).Value;
...
Why is the collection empty, when there are controls drawn on the screen?
Thanks a lot for any help; this is starting to drive me nuts.
(BTW: I tried adding/removing the EnableViewState="true" tag)
Have you made sure the repeater has been rebound on the postback?
The ASP.NET Page Life Cycle means that on a postback, you will need to rebind controls like the repeater in order for event handlers to be able to see the data.
Check if you have a Page.DataBind() in the page code behind. That makes your repeater to bind with empty data.
Maybe you do the databinding every time you load the page, do you check that there is no postbacl before you do it ?
I believe Items is only populated when bound. So you have to rebind your data on every page load. This is due to the statless environment of the web; it doesn't remember the data source, but loads the created controls from viewstate that were bound to it.
So on subsequent requests, it loads the control hierarchy but knows nothing about the data source that created the UI unless you rebind again.
HTH.

Aspx Property Interpolation

I'm a bit new to .Net development, been working in Java for some time now. I have an aspx page and we need to externalize some strings to make it more flexible.
If I have a table somewhere and there is just a string sitting outside an asp tag, I can replace it so that
<th> Specific Foo String </th>
becomes
<th> <%= Strings.foo %> </th>
and everything is fine, the problem I'm running into is how do you do this kind of interpolation on an asp tag property
I tried changing
<asp:Label runat="server" ID="lblFoo" Text="Specific Foo String Entry" />
to
<asp:Label runat="server" ID="lblFoo" Text='<%= Strings.foo %> Entry' />
and
<asp:Label runat="server" ID="lblFoo" Text='<%#Eval("Strings.foo") %> Entry' />
but neither worked. Is what I'm doing not possible in the aspx file, I know that I can simulate this by rewriting their properties in the code behind, but that's a level of overhead I'd rather not deal with.
Thanks
I think you are looking to do this:
<asp:Label runat="server" id="label1" Text='<%# Strings.Foo + " Entry"%>' />
Then in your code behind (most likely in your OnPageLoad) you need to call
if(!Page.IsPostBack) Page.DataBind();
You need to be cautious however as calling DataBind on controls like textboxes or any labels that may have changed due to logic in the code behind will have their values overwritten with the bound values. Checking that you are not on a post back can help with this, but there are still gotchas.
Also note that I had to move the " Entry" text into the binding statement. If it is placed outside the last '%>' then the binding does not work and it will spit out:
<%# Strings.foo %> Entry
In the codebehind of the page you would do this:
lblFoo.Text = Strings.foo + " Entry";
A good place to put this code would be in the overriden OnLoad method but that is simply a suggestion as I am unfamiliar with your application and the life cycle needs of your page.
If you want to do all this in the aspx page then simply do this:
<span><%= Strings.foo %> Entry</span>
as a Label renders as a span anyhow.
If your objective is an HTML table of strings, then you can create either a ListView or a GridView and DataBind to that. It would save you the trouble of writing out all of your properties and will also produce the correct table tags for the data.
Without knowing more about your data, I cannot provide a detailed code snippet.
You're talking about resources. Read Basic Instincts Resources and Localization in ASP.NET 2.0 which shows you the built in resource editor, and how to use the "<%$ ... %>"-binding, or using meta:resourceKey attribute.

How do I make my ASP.NET server control take an embedded code block as a property value?

I have a custom server control with a property of Title. When using the control, I'd like to set the value of the title in the aspx page like so:
<cc1:customControl runat="server" Title='<%= PagePropertyValue%>' >
more content
</cc1:customControl>
When I do this, however, I am getting the exact String <%= PagePropertyValue%> being displayed rather than the Property Value that I would like to see.
So after trying the databinding expression (as suggested below). I don't get the string literal that looked bad but I don't get anything else either.
<cc1:customControl runat="server" Title='<%# PagePropertyValue%>' >
more content
</cc1:customControl>
What do I need to do to my custom control to take this sort of value? Or is there something I need to do to the page.
You cant. <%= %> will write the string directly to the response-stream, which happens after the server control is constructed. See this post for an explanation.
So its either codebehind, or <%# + databinding as Zachary suggests.
As a followup to my own question, I have discovered that what I really wanted was to use ASP.NET Expressions using the <%$ syntax, since what I wanted to do was put in localized content.
This can be done with apparently no extra handling on the server control side.
<cc1:customControl runat="server" Title='<%$ Resouces: ResourceFile, ContentKey %>' >
more content and controls
</cc1:customControl>
This works just fine.
Try using databinding syntax:
<%# PagePropertyValue %>
For the bind property value to work correctly as suggested, you will have this in the aspx or ascx file :
<cc1:customControl runat="server" Title='<%# PagePropertyValue %>' >
more content
</cc1:customControl>
You will then need to actually bind data in your page wich you have to add this in you code behind file (code in C#)
protected void Page_Load(object sender, EventArgs e)
{
DataBind();
}
That way it will bind the data in your ascx or aspx file.
Note that this is specific to control attributes. When using the <%= syntax outside control attributes meaning anywhere else in the page the syntax works as expected. So this
<%=GetCapitalUserName()%>
would call the correct method and inject the result of the call in the page.

How to populate UpdatePanel in Repeater in ASPX (not code-behind)?

I have a Repeater which displays a list of items (in a grid-like/table view). When a user clicks an item, I display an UpdatePanel under this item with additional information relevant to the item (similar to Accordion control). I know how to populate the elements of the UpdatePanel in code-behind (I pass the ID of the selected element in the Repeater control as CommandArgument, get additional info for this ID, and set up the text fields of the active UpdatePanel controls). But I'm wondering if I could set up binding directly in the ASPX (instead of code-behind). When I used the <%= %> syntax to assign text fields of the UpdatePanel control the values of the page properties, e.g. <%= Comment %>, it sort of worked, but it changed the fields of all UpdatePanels in the repeater. Is there any way to bind the active UpdatePanel to the current values and leave already bound UpdatePanels unchanged?
Are you looking to display a container that displays additional information? Is there other activity in the "box" that requires it be an updatepanel?
<asp:repeater>
<itemtemplate>
<%# Eval("Name") %> <%# Eval("LastName") %><br />
<span onclick="$get('<%# Eval("Id") %>')">View Age</span>
<div id="<%# Eval("Id")%>" style="display:none;">
Age: <%# Eval("Age") %>
</div>
<itemtemplate>
</asp:repeater>
Ithink that's right, some syntax may be off a bit (typing without intellisense). Would that work?
I used ID as a unique identifier for the div id and the onclick command. You could also use jquery, asp:controls or whatever else you wanted.
Easiest way is to nest a FormView inside the update panel. Then the only thing you need to do in the code behind is get the additional info, assign it to the FormView.DataSource, and call FormView.DataBind(). Everything in the FormView will use the <%# Eval("SomeColumn") %> syntax. You'll probably need to use a FindControl() to get a reference to the FormView. I'd type up the code for you but I'll save you some headaches down the road and say DON'T DO THIS.
The update panel is about the most inefficient way to do any ajax stuff. The only way to get it all to wire up correctly with this repeater and server side code is to either have a gigantic viewstate or to rebind the repeater in your page load. You are turning a request that could be 300ms into something that will take over a second...or longer! Get familiar with a good ajax framework and don't be afraid to write real html. At the very least, use a webservice that loads a usercontrol with your markup.
I know the update panel is easy, and it's built in. It might even be adequate for what you are doing, but you must resist. You'll be glad you did.

Resources