A tricky way to using <%# Bind %> in ASP.NET - asp.net

In ASP.NET, I can use <%# Bind %> to achieve two-way data binding, then the data source control can complete update function for me.
However, I think it's only easy when you just show simple format, like
<%# Bind("InsertDate") %>
But, if I want to show 'N/A' when InsertDate is not exist. then how to use <%# Bind %> to achieve the condition check?
I know Bind function supports format string, like
<%# Bind("InsertDate", "0:{dd MMM yyyy}") %>
But it cannot change format base on InsertDate's content.
I even try to use:
<%# FormatString(Bind("InsertDate").ToString()) %>
It seems's not working which normally works for Eval function.
Another example is I have a bitwise column in table (like 5) which is represented by a checkboxlist wrapped by ListView control, like
<asp:checkboxlist>
<asp:ListItem value="1" text="OptionA">
<asp:ListItem value="2" text="OptionB">
<asp:ListItem value="4" text="OptionC">
</asp:checkboxlist>
then how to use <%# Bind %> to achieve two-way bind to bind the bitwise column to this checkboxlist?
Currently what I do is:
set checkboxlist's selected item(value) in ListView's ItemDataBound event handler
using a HiddenField and bind the data to this hiddenfield to
achieve two-way data bind.
In LivtView's ItemUpdating event handler, I update above ListViewUpdateEventArgs' NewValue property to the value I want. and then the EntityDataSource can do the update operation correctly.
But I think this method is not easy and good.
So is there any other better method to do this?

Try to make use of the public data type.
On your code-behind declare your variable as
public string name;
//Do whatever assignment operations to your variable "name"
And on your aspx page. You can call it
<% Response.Write(name); %>

Related

Totally lost – data binding expressions inside GridView’s template

1) On aspx page we define GridView control named gvwPolls, and inside its template we define a user control named pollBox1
<asp:GridView ID="GridView1" DataSourceID="objPolls" ...>
<Columns>
<asp:TemplateField>
<ItemTemplate>
Question is : <%# Eval("QuestionText") %> <br />
<mb:PollBox ID="PollBox1" runat="server" PollID='<%# Eval("ID") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="objPolls" ...></asp:ObjectDataSource>
a) I assume that inside gvwPolls’s template, the gvwPollBox1.DataBind is called before PollID='<%# Eval("ID") %>' and <%# Eval("QuestionText") %> expressions get evaluated?!
b) Can someone offer some explanation how or why is gvwPollBox1.DataBind called before PollID='<%# Eval("ID") %>' and <%# Eval("QuestionText") %> expressions get evaluated?
2) Continuing with the above example:
-- pollBox1 user control defines a Repeater control named rptOptions:
<asp:Repeater runat="server" ID="rptOptions">
<ItemTemplate>
<%# Eval("pollBoxTitle") %>
</ItemTemplate>
</asp:Repeater>
-- In pollBox1’s code-behind file we bind rptOptions to a data source inside DoBinding() method.
-- We also override pollBox1’s DataBind() method:
public override void DataBind()
{
base.DataBind();
DoBinding();
}
a) I assume that due to overriding pollBox1.DataBind(), the data binding expression <%# Eval("pollBoxTitle") %> ( defined inside rptOptions’s template ) will get evaluated prior to a call to DoBinding method? If so, won’t then <%# Eval("pollBoxTitle") %> get evaluated before rptOptions is actually bound to a data source?
b) If that is the case, how then is rptOptions able to extract value ( from data source’s pollBoxtitle property) from a data source, if at the time the <%# Eval("pollBoxTitle") %>
expression got evaluated, rptOptions wasn’t yet bound to any data source?
thanx
I can't explain why the page life cycle is the way that is, probably has something to do with rendering childs before the parent object. When exactly do you call .DataBind() in the PollBox control? Try to move it into an event that is later in the life cycle, like PreRender.
There is also another way to ensure it is working the way you want to:
Subscribe to the RowDataBound Event, use .FindControl("YourPollBoxID") to get the instance of the control current bound row, set the properties and perform a manuall .DataBind();

nested repeater pass value in header template

I have a nested repeater and i want to pass value in its header. Here is my code so far..
The main problem is the id of the control in header template is also coming from code behind.
<asp:Repeater ID="RptrProgCategory" runat="server">
<ItemTemplate>
<asp:Repeater ID="RptrPrograms" runat="server">
<HeaderTemplate><input type="hidden" id="<%= questvalue%>"/></HeaderTemplate>
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "cat") %>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
I want value in questvalue from code behind. Any idea how to achieve this?
Edit: I wanted to put this value in a DataTable and bind that value in Repeater bcoz i want output like this may be <%# DataBinder.Eval(Container.DataItem, "questvalue") %> instead of <%= questvalue%>..but in tht case i am not able to find the control
Category1(id of hidden field )
subcat1
subcat2
subcat3
Category2(id of hidden field)
subcat4
subcat5..and so on..
Repeater mainRepeater = this.Page.FindControl("RptrProgCategory") as Repeater;
Repeater nestedRepeater = mainRepeater.FindControl("RptrProgCategory") as Repeater;
You can then do a FindControl in nestedRepeater for questValue.
Add a runat='server' to questvalue so that you can access it in code behind.
I am writing this from memory, syntax might not be correct but it should get you off in the right direction.
set the id of the control in the repeater to something like mycontrolId - and then on OnItemDataBound - (or even OnItemCreated) use findcontrol("mycontrolId") - and then change the id of the control to your questvalue param.

Can I use <%= ... %> to set a control property in ASP.NET?

<asp:TextBox ID="tbName" CssClass="formField" MaxLength="<%=Constants.MaxCharacterLengthOfGameName %>" runat="server"></asp:TextBox>
The code above does not work. I can set the MaxLength property of the textbox in the code behind but i rather not. Is there away I can set the MaxLength property in the front-end code as above?
You could use DataBinding:
<asp:TextBox
ID="tbName"
CssClass="formField"
MaxLength="<%# Constants.MaxCharacterLengthOfGameName %>"
runat="server">
</asp:TextBox>
and in your code behind Page_Load call:
tbName.DataBind();
or directly databind the page:
this.DataBind();
The <%= expression %> syntax is translated into Response.Write(expression), injecting the value of expression into the page's rendered output. Because <%= expression %> is translated into (essentially) a Response.Write these statements cannot be used to set the values of Web control properties. In other words, you cannot have markup like the following:
<asp:Label runat="server" id="CurrentTime" Text="<%= DateTime.Now.ToString() %>" />
Source: https://web.archive.org/web/20210513211719/http://aspnet.4guysfromrolla.com/articles/022509-1.aspx
Try to use custom expression builder:
// from http://weblogs.asp.net/infinitiesloop/archive/2006/08/09/The-CodeExpressionBuilder.aspx
[ExpressionPrefix("Code")]
public class CodeExpressionBuilder : System.Web.Compilation.ExpressionBuilder
{
public override CodeExpression GetCodeExpression(BoundPropertyEntry entry,
object parsedData, ExpressionBuilderContext context)
{
return new CodeSnippetExpression(entry.Expression);
}
}
And then use it like
<asp:TextBox ID="tbName" CssClass="formField" MaxLength="<%$ Code: Constants.MaxCharacterLengthOfGameName %>" runat="server"></asp:TextBox>
As Ropstah said, it isn't going to work with the <%= expression %> syntax.
But you could probably use databinding, which just requires that you use the <%# expression %> syntax and then call MyTextBox.Databind in CodeBehind.
Of course, at that point it might be more clear to just do the whole operation in CodeBehind.
Another alternative: if you really want this to be declarative, you could get away from the Label and embed your expression in a span tag.That way you still get to apply CSS, etc and I think the <%= expression %> syntax would work.
Why don't you just set it in the Page_Init callback function in the code behind?
This example is geared towards getting the max length from underlying sql types in linq. But you should be able to customise it to your needs
http://blog.binaryocean.com/2008/02/24/TextBoxMaxLengthFromLINQMetaData.aspx
It looks like you want to be able to control the max length of a specific type of text box from a single location so that if that max length needs to change, you only need to change it in one place.
You can accomplish this by using a skin file. You set the max length in the skin file as you would normally and then any textbox that uses that max length would use the skin. If the length changes then you only need to change the skin file.
You can do it with databinding
<asp:TextBox
ID="tbName"
CssClass="formField"
MaxLength='<%# Constants.MaxCharacterLengthOfGameName %>'
runat="server" />
Then in the code behind
protected void Page_Load(object sender, EventArgs e) {
Page.DataBind();
}
You can embed "normal" code in the .aspx file if you so want, like:
<%
tbName.MaxLength = Constants.MaxCharacterLengthOfGameName
%>
<asp:TextBox ID="tbName" CssClass="formField" runat="server"></asp:TextBox>
This harkens back to an older style "classic" ASP way of doing this.

Passing data from listview controls

My listview is displaying data for a product item. In my template I want to display data based on the id of a product by calling a function that takes the id as a parameter. How is this done?
If it is .NET 2.0 or above you can use this:
<ItemTemplate>
<%# SomeFunction((int)Eval("myIdColumn")) %>
</ItemTemplate>
Note that the SomeFunction must be protected or 'higher' for this to work at all.
You should be able to do something like this:
<ItemTemplate>
...
...
<%# myFunction((int)DataBinder.Eval(Container.DataItem, 'myIdColumn')) %>
...
...
</ItemTemplate>
You custom function (myFunction() in the example above) should return a string.

ASP.NET custom control rendering before <%= %> code executes to populate property

I have a custom control that exposes a property. When I set it using a fixed value, everything works correctly. But if I try to set its value using the <%= %> tags, it goes a little whacky:
<cc:CustomControl ID="CustomControl" runat="server" Property1='<%= MyProperty %>' />
<%= MyProperty %>
When this gets rendered, the <%= MyProperty %> tag underneat the custom control is rendered as I expect (with the value of MyProperty). However, when I step into the Render function of the CustomControl, the value for Property1 is literally the string "<%= MyProperty %>" instead of the actual underlying value of MyProperty.
You control is initialized from the markup during OnInit. So if that syntax worked, it wouldn't have the effect you wanted anyway, since MyProperty would be evaluated during OnInit and not at render time (like it is with the second usage).
You want to use the data binding syntax instead:
<cc:CustomControl ID="CustomControl" runat="server" Property1='<%# MyProperty %>' />
Just make sure to call DataBind() on the container (Page, UserControl, etc).
Alternatively, you can set the property in your code behind:
CustomControl.Property1 = MyProperty;
Try <%# MyProperty %> in the CustomControl and see if that works.

Resources