Best Technique for Multiple Eval Fields in Gridview ItemTemplate? - asp.net

What is the best way to use multiple EVAL fields in a GridView ItemTemplate?
Looking to have some control over formatting for appearance as well as setting up hyperlinks/javascript etc.

Even clearer, IMO, is:
<%# String.Format("{0} - {1}", Eval("Name1"), Eval("Name2")) %>

I had previously used this (bad, I know):
<%# Eval("Name1", "{0} - ")%> <%#Eval("Name2")%>
Result = 'John - Smith'
But just discovered that I can also put TWO (or more) Evals in the same data-bound group:
<%#Eval("Name1") & " - " & Eval("Name2")%>
Result = 'John - Smith'
Or
<%# "First Name - " & Eval("Name1") & ", Last Name - " & Eval("Name2")%>
Result = 'First Name - John, Last Name - Smith'

Eval and Bind both suck.
Why get the property through reflection? You can access it directly like this:
((MyObject)Container.DataItem).MyProperty
It's not like the object is unknown to you at runtime. That's my two cents, anyhow.

I have a easiest way to do this same thing...
<asp:Label ID="lblName" runat="server" Text='<%#Eval("FirstName").ToString() +", "+ Eval("LastName").ToString() %>'></asp:Label>
.
<%#Eval("FirstName").ToString() +", "+ Eval("LastName").ToString() %>
Here both objects are converted into string the concatenate them.

Related

Input string was not in a correct format error when passing values of decimal data type as querystring

We have the following field names in our database with data type of decimal:
RentalFee
ExtraHourFee
CancelFee
KeyDeposit
When attempting to pass their values as querystring from one page to another, we run into Input string was not in a correct format error.
Here is a snippet of the markup:
<asp:TemplateField HeaderText="Select" SortExpression="siteid">
<ItemTemplate>
<asp:HyperLink ID="hdReserve" Text="Select" runat="server"
NavigateUrl='<%# "Reserve.aspx?id=" + Eval("siteId") + "&groupsize=" + ddlPartySize.SelectedValue + "&facilityFees= " + Eval("RentalFeeAmount") + "&facilityFees= " + Eval("RentalFeeAmount") + "&depoitAmt= " + Eval("DepositAmount") + "&cancelAmt= " + Eval("CancellationAmount") + "&keydeptAmt= " + Eval("KeyDepositAmount") %>' />
</ItemTemplate>
</asp:TemplateField>
Then the values are grabbed from codebehind:
Dim intRentalFee As Decimal
Dim intExtraHourFee As Decimal
Dim intCancelFee As Decimal
Dim intKeyDeposit As Decimal
rentalfeeHide.Text = Request.QueryString("facilityfees")
extrahrfeeHide.Text = Request.QueryString("extrahour")
cancelfeeHide.Text = Request.QueryString("cancelAmt")
keydepositfeeHide.Text = Request.QueryString("keydeptAmt")
intRentalFee = rentalfeeHide.Text
intExtraHourFee = extrahrfeeHide.Text
intCancelFee = cancelfeeHide.Text
intKeyDeposit = keydepositfeeHide.Text
' Add all up to get total fee
lblTotal.Text = intRentalFee + intExtraHourFee + intCancelFee + intKeyDeposit
Any ideas how to resolve this?
I would use the following instead as it is very difficult to see what is happening:
<asp:hyperlinkfield datatextfield="UnitPrice"
datanavigateurlfields="siteId,groupsize,facilityFees"
datanavigateurlformatstring="~/details.aspx?siteId={0}&groupsize={1}&facilityFees={2}" />
The above only demonstrates a few fields but it uses datanavigateurlformatstring for the url and datanavigateurlfields for the arguments which can be specified with a comma-separated string.
MSDN Hyperlink reference
You should then be able to clearly see in the url what the values are and check that they match your intended type for the destination page and convert them i.e.
var facilityfees = Convert.ToDecimal(Request.QueryString("facilityfees"));
Do in in code behind...
hdReserve.NavigateUrl = string.Format("../Reserve.aspx?id=?id={0}&groupsize={1}&facilityFees={2}...", siteId, ddlPartySize.SelectedValue, intExtraHourFee...)
In addition to Huchanoid's answer you need to make some mods to your codebehind.
First off you say the values are decimal but you are using them as integers? Which are they?
Next, what is the querystrings don't exists... someone just types in the page name... I would say you need to check that these values exist and then cast them as integers (or Decimal)... Use
If Not IsNothing(Request.QueryString("yourQueryStringName")) Then
'check that they are numeric or use a try catch...
If isNumeric(Request.QueryString("yourQueryStringName")) Then
'Querystring is Numeric
intYourQueryStringName = Cint(Request.QueryString("yourQueryStringName"))
Else
'Error Querystring is not numeric
Response.Redirect("Somwhere.aspx")
End If
Else
'QueryString does not exist
Response.Redirect("Somwhere.aspx")
End If

The server tag is not well formed error in WhereCondition=

I know the error is caused by the <%# Eval("NodeID")%> statement. When I put a literal integer, it works fine. I tried changing the outside double quotes of the WhereCondition to single quotes, and the inside quotes to double quotes, but this throws an exception.
<cms:CMSRepeater ID="subcatPreviewImages" Path= '<%# Eval("NodeAliasPath") + "/%" %>' runat="server" ClassNames="CMS.MenuItem" TransformationName="EcommerceSite.Transformations.EMCategorySmallImagePreview" OrderBy="NodeLevel, NodeOrder, NodeName" MaxRelativeLevel="4" WhereCondition="DocumentMenuItemHideInNavigation='false' AND NodeParentID= <%# Eval("NodeID")%> AND NodeLevel=3" />
You need to build your string inside the databind tag like you did with the NodeAliasPath property:
WhereCondition='<%# "DocumentMenuItemHideInNavigation='false' AND NodeParentID=" + Eval("NodeID") + " AND NodeLevel=3" %>'
If you are having trouble with the mixed ' and " characters, you may want to move the logic that builds the expression into a function in your page:
public string GetWhereCondition(SomeType dataItem) {
return "..." + dataItem.NodeID + "...";
}
And the your tag changes to:
WhereCondition="<%# GetWhereCondition(Container.DataItem) %>"
Disclaimer: function and type names are made up for example only -- please use appropriately named functions and replace my poorly-named ones.

replace spaces with from a recordset

How can I change "spaces" on records being returned by a recordset?
For example, I have this code that will return a value of "John Doe":
<td width="30%"><%=rsTmp("Name")%></font></td>
What I would like to do is to change the space between the words into:
so that when my page got congested the name "John Doe" will still be in a straight line, and will not be separated?
In Classic ASP you will need to code the following:
<%= Replace(rsTmp("Name")," "," ") %>
Which is the same as
<%
Response.Write ( Replace(rsTmp("Name")," "," ") )
%>
Actually, I would suggest using replace(rsTmp("Name"), " ", " ")
In HTML5 the ASCII code are replaced with  . You might as well do this from this day and onwards ;)
I resolved it!
I used replace function like this.
<% Replace(rsTmp("Name")," "," ")%>

gridview row eval: column as name parameter instead of index

I have a gridview and the OnRowDataBound event is linked to this function:
if (e.Row.RowType == DataControlRowType.DataRow)
{
ThisRow = e.Row.DataItem as MyObjectModel;
if (ThisRow.Property1 == null) { e.Row.Cells[5].Text = "-"; }
This code looks at the value of a property of the object in the data source and if it's null, converts the null to display "-" in column 5. The problem I'm having is that if I change the order of the columns of the gridview, then I need to change the index of every other modification.
What I'd like to do is change the statement "e.Row.Cells[5].Text" to something that says "the cell whose column header is xyz".
Any suggestions?
Thanks.
I think you might be better off handling this in your gridview code rather than your code behind, especially if you are shuffling columns around.
Here's an example with ponies. Feel free to edit as needed.
<asp:TemplateField HeaderText="Likes Ponies?">
<ItemTemplate>
<asp:Label ID="uxLikesPoniesLabel" runat="server" Text=’<%#
DataBinder.Eval(Container.DataItem, "FavoritePonies").ToString() == "" ?
"I like " + DataBinder.Eval(Container.DataItem, "FavoritePonies") + " Ponies!" :
"-"
%>’ />
</ItemTemplate>
</asp:TemplateField>
I'm using the C# (boolean condition) ? "value if true" : "value if false" here.
So, this code would check to see if the FavoritePonies column in the particular row is "" (because NULL values are displayed as empty string) and if so, it displays "-" instead. If it's not null, then it displays what was originally in the database with DataBinder.Eval(Container.DataItem, "FavoritePonies") as "I like Ponies!".

Custom Repeater with hiractial Databinding

Im using a Custom NestedRepeater Control for ASP.NET which can be found on code project
The source is in c# which i have converted to vb and plugged into my solution, so far so good. The problem, im having is databinding to the repeater, my code behind looks like this...
'' get all pages
Dim navPages As DataSet = Navigation.getMenuStructure()
navPages.Relations.Add(navPages.Tables(0).Columns("ID"), navPages.Tables(0).Columns("ParentID"))
NestedRepeaterNavigation.RelationName = RelationName
NestedRepeaterNavigation.DataSource = navPages
NestedRepeaterNavigation.RowFilterTop = "ParentID is null"
NestedRepeaterNavigation.DataBind()
Then in the item template of my custom repeater im trying the following...
<ItemTemplate>
<img src="/pix.gif" height="10" width="<%#(Container.Depth * 10)%>">
<%# (Container.DataItem as DataRow)["DESCRIPTION"]%>
<%# (Container.NbChildren != 0 ? "<small><i>(" + Container.NbChildren.ToString() +")</i></small>" "") %><small><i></i></small>
</ItemTemplate>
The databinding falls over; firstly that 'as DataRow' says it was expecting an ')'. And secondly that '!=' identifier expected.
Is this due to the translation from c#, should the databinding be different?
Though I've not programmed in VB.net for long (about 3 years) but I know that AS is not applicable in VB.net you need ctype to cast Container.DataItem like
CType(Container.DataItem, DataRow).
you can also try DirectCast(Container.DataItem, DataRow) but I don't think this will work.
Also for inequality comparison you can use
Not Container.DataItem = 0
but not !=

Resources