ASP.NET 2 Control Properties Databinding does not always work - asp.net

I've got the beautiful task at hand to look at some nice legacy asp.net 2 code and implement some new controls.
It's my first attempt at asp.net (the classic one, i've experimented with mvc a bit) so i am not too fond of it.
Right now i am trying to understand why a databinding sometimes works and a similar binding wont work on another page.
<asp:ImageButton ID="SaveAsPDFButton" runat="server"
ImageUrl='<%#GetPdfIconSmallPath() %>'
ToolTip='<%$ Resources:SaveAsPDFButton.Text %>'
CausesValidation="false" />
While the Tooltip gets evaluated and set, the ImageUrl of this control wont be set. The function is not getting executed. I've tried all, even disabling ViewState on it.
On other places, this same code however works just fine, like this small snippet here which does exactly what you might expect it to do:
<asp:HyperLink ID="InvHl" runat="server">
<asp:Image ID="Img1" ImageUrl='<%#GetPdfIconSmallPath() %>' runat="server" />
</asp:HyperLink>
Same thing occurs with the Visible Property of an ASP:Panel i have on other places in this page.
Any ideas on how to get this working appreciated!

We didnt really solve the problem but switched to the newest version of ASP.NET which does not show such a strange behaviour.

Related

Pass variable used in aspx page to user control

We are in ASP.Net Webforms. I come from a LAMP Stack mindset...
ASPX Code (part of it)
<asp:Content runat="server" ContentPlaceHolderID="PH_MainContent">
<h3 class="fleft">
<asp:Literal runat="server" ID="li_title" />
...
<Example:userControl runat="server" someVariable="text" otherVariable=<%=li_title.Text%> thirdVariable=<%=Items["sort"].toString()%> />
So, li_title is a literal set in the code behind, I want to reuse it later, passing it to a userControl, where it shall be displayed in a javascript. Items is page.Items. I have also tried this.li_title (which is suggested to me in Visual Studio 2015).
After reading "quite a few" very similar questions, this seem the solution. However obviously I'm missing the point. What would that be..?
You can create a public property for each variable on your user control and set them in aspx. See this for more information

Script control is not a registered script control

I have a page that uses CustomerDetails.ascx. It uses CM.ascx. Inside CM.ascx I use AJAX Data Controls GridView with ID="gdvRecommendation".
Sometimes when I browse to the page I get the following exception:
Script control 'gdvRecommendation' is not a registered script control. Script controls must be registered using RegisterScriptControl() before calling RegisterScriptDescriptors().
Parameter name: scriptControl
My ScriptManager defined in the master page before the content place holder.
This exception doesn't happened always.
I use CustomerDetails.ascx user controls in other pages and it works great.
Can anyone explain me the problem and what can be the solution?
Edit:
Here is the GridView usage in CM.ascx:
<td valign="top" style="height: 150px;">
<div id="divCMMessage"></div>
<div id='divRecommendation' style="width: 100%; display: inline; overflow: auto;">
<ADC:GridView ID="gdvRecommendation" Width="100%" runat="server" CellSpacing="0" CellPadding="3" HorizontalAlign="Right" ShowHeader="false" RowDataBoundEvent="onRowDataBound_gdvRecommendation">
<RowStyle Height="20px" />
<EmptyDataTemplate>no recommendations</EmptyDataTemplate>
<EmptyDataRowStyle HorizontalAlign="Right" BorderWidth="0" />
<Columns>
<ADC:GridViewImageColumn DataImageUrlField="IndImageUrl" HeaderText="" ItemStyle-Width="25px" ItemStyle-HorizontalAlign="Center"></ADC:GridViewImageColumn>
<ADC:GridViewTemplateColumn HeaderText="">
<ItemTemplate>
<asp:Label ID="TreatName" runat="server" Text=""></asp:Label>
</ItemTemplate>
</ADC:GridViewTemplateColumn>
<ADC:GridViewTemplateColumn HeaderText="">
<ItemTemplate>
<asp:Label ID="TreatType" runat="server" Text=""></asp:Label>
</ItemTemplate>
</ADC:GridViewTemplateColumn>
</Columns>
</ADC:GridView>
</div>
</td>
The CustomerDetails.ascx is inside a MultiView (on MyPage.aspx).
I had a similar problem myself and this post helped me to understand my errors:
==============================================
Script control 'ControlName' is not a registered script control
So you're here because you got the following error.
Script control 'ControlName' is not a registered script control. Script controls must be registered using RegisterScriptControl() before calling RegisterScriptDescriptors().
Parameter name: scriptControl
  
I myself have done a fair bit of googling on this, and there are many
solutions given all over the net. unfortunately these are all very
scenario specific solutions. Some people get their answers, and the
others, like me, don't.
Answer:
You are changing the visibility of a control at the wrong stage of the
page life cycle.
Description:
If you are changing the visibility of a control, you should always do
it during, or before the PreRender event. If you do it after (i.e. in
a End handler of an async task or during PreRenderComplete) you might
run in to this issue.
This is not an issue for simple controls such as buttons or text
boxes. But it will have adverse effects on controls such as grids.
When I say changing the visibility it could be any one of the
following situations
Having visible=false of a control during the early stages of the life cycle and being changed to visible=true during an end handler or PreRenderComplete
Changing the selected view of a MultiView during an end handler or PreRenderComplete
Any other situation where the control may not be visible during the earlier stages of the page life cycle which are set to be visible during the latter stage
 
Reason:
Purely
from my understanding, ASP.NET does not render the scripts or the HTML
related to a control if it is not being shown to the user. The
registering of script controls which is mentioned in the exception
seem to happen during an early stage of the life cycle. if the control
is not visible at this stage, this registration is skipped for that
control. If it's made to be visible at a latter point, you get
yourself a control without some of the relevant scripts.
Anyway this is what I have understood. I may be wrong. But if you come
across this issue, it will definitely help you to check for controls
which are changing visibility at different points of the life cycle.
You will be able to identify your specific problem by doing this and
then come up with a solution on your own.
Hope this information helps some one.
============================
Source
I faced same problem recently, above solution did not work for me. I was Hiding a control and later making it visible in PreRender based on some condition check. Hiding was working fine but when I was making it visible again, it was giving me the same error.
below is What worked for me is-
ScriptManager sm = ScriptManager.GetCurrent(Page);
sm.RegisterScriptControl(control_name);
Then making the control visible resolved my issue.
control_name.Visible = true;
Hopefully it may help someone facing this issue.
I had a similar issue with AJAX, and amusingly it occured only when in 'Debug' mode. In release mode, everything works fine. I have not reached to a conclusion on it yet.
You may want to give it a shot.
In case of a RadAjaxPanel and loading UserControls, reading the answer from jhfelectric, I came up with the following solution (simple one):
Disable AJAX on load (Me.EnableAJAX = False) and Enable it on PreRender. Because PreRender isnot called when removing a control, and is called after adding a control.
You can get this Exception when you have a RadAjaxManager in a user control that itself is also inside a RadAjaxManager, either directly or as the child of another user control.

Checkbox in GridView not persistent ASP.NET

I am having issues with this GridView. I update it in design mode, and the update does not make it to the code behind section. For example, I add field "xyz". Gridview says "xyz" fields exist in design mode. In code-behind, it does not exist. when you view the page in browser, ofcoure "xyz" field is not shown. After refresh, even the gridview looses this field in design mode. So ok I got around this problem and managed to add a template field which is now working.
Now the problem is, the checkbox that I added in one of the column is not persistent. I have a button which works on the selected values of checkboxes but each time I click the button, the page refereshes and all the checked values are lost (checked values becomes unchecked).
Does anyone has any idea?
Want to mention, I am working with a bit messy code. But dont want to change a lot at this time.
<asp:TemplateField HeaderText="All" >
<HeaderTemplate>
<asp:CheckBox ID="chkAll" runat="server" name="chkAll" />
</HeaderTemplate>
<EditItemTemplate>
</EditItemTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkRow" runat="server" />
</ItemTemplate>
</asp:TemplateField>
This took me a couple of days to figure out myself. Since my code was quite messy, it was hard to troubleshoot.
I put in some code in page_load default event that finally fixed. Don't know if I was putting code in the wrong place first. It definitely took some time though.

ASP.Net - Two way databinding of a single entity - Options, best way...roll your own?

I have been searching around to find the best option of doing this.
Basically, I want to do two way databinding of multiple controls (textbox, dropdownlist, checkbox, etc) to a single instance of custom class/entity, ie: Person.
It seems, the (only?) way to do this is using an like so:
<asp:FormView ID="FormView1" runat="server" DataKeyNames="OrderID"
DataSourceID="SqlDataSource1" DefaultMode="Edit">
<EditItemTemplate>
OrderID:
<asp:Label ID="OrderIDLabel1" runat="server" Text='<%# Eval("OrderID") %>' />
<br />
CustomerID:
<asp:DropDownList ID="CustomerIDDropDownList" runat="server"
DataValueField='CustomerID' DataSourceID="CustomerDataSource"
DataTextField="CompanyName"
SelectedValue='<%# Bind("CustomerID") %>'
/>
EmployeeID:
<asp:TextBox ID="EmployeeIDTextBox" runat="server"
Text='<%# Bind("EmployeeID") %>' />
<br />
Some issues:
- This is limited to using an ObjectDataSource control (ie: can't just use an instance of the desired class in the code behind)
- Forces you to define a second (likely identical layout) read only template....would be nice to have some some mechanism that could intelligently render a read-only view derived from the edit template.
- The binding declaration Text='<%# Bind("EmployeeID") %>' is loosely typed, so vulnerable to spelling errors
- etc
So my first question I guess is, is an asp:FormView the only way in ASP.Net to do declarative databinding of a single entity?
Secondly, how feasible would it be to hand roll some sort of a two way binding mechanism? I guess it would have to be reflection based, but I could live with that. Anyone recommendations on how one would declare the binding relationships in the aspx page? Would the proper way be like:
Text='<%# MySuperDuperBind("EmployeeID") %>'
And then somewhere (where?) my MySuperDuperBind implementation will get called as the page is rendered....how this is done is a bit beyond me though. And if I want to render in readonly, I can call a secondary function that will remove the editable UI control from the form and replace it with the corresponding read only version (ie: a Textbox is replaced with a Label).
Another alternative route is getting away from webforms and going to a client side templating solution such as this very nice looking solution:
http://weblogs.asp.net/dwahlin/archive/2009/05/03/using-jquery-with-client-side-data-binding-templates.aspx
However, I have no clue how to write the asp.net webservices properly in order to retrieve and save data in this type of an architecture.
Ideas?
is an asp:FormView the only way in
ASP.Net to do declarative databinding
of a single entity?
There's also DetailsView but it has the same issues.
I've mostly given up on 2-way databinding. It's great for prototyping and gets me 80-90% of the way to a complete solution but the last 10-20% is a nightmare. Binding any non-trivial object always seems to involve so many event handlers to customize behavior that it feels like spaghetti code to me.
I usually have two methods:
MapEntityToView(entity)
MapViewToEntity(entity)
that I call to display the entity and to populate from the page, respectively. It can be tedious to write but I don't have to wrestle with data binding issues.
I do use 1-way binding extensively for read only pages and displaying items in list controls.

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.

Resources