gridview row eval: column as name parameter instead of index - asp.net

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!".

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

How do you handle NULL values in DataBound controls?

I am trying to limit the characters displayed in ASP.NET Label controls that have their Text values databound to a SQL Database. If the field in the database is not NULL, I do not have any trouble. If they are NULL, I get the exception "Object reference not set to an instance of an object."
My code is as follows:
<asp:Label ID="LabelDescriptionLabel" runat="server" Text='<%# IIf(Not IsDBNull(Item.LabelDescription), IIf(Item.LabelDescription.ToString.Length > 30, Left(Item.LabelDescription, 30) & "...", Item.LabelDescription), Item.LabelDescription)%>' />
I have also tried the following, without any luck:
<asp:Label ID="LabelDescriptionLabel" runat="server" Text='<%# IIf(Not IsNothing(Item.LabelDescription), IIf(Item.LabelDescription.ToString.Length > 30, Left(Item.LabelDescription, 30) & "...", Item.LabelDescription), Item.LabelDescription)%>' />
I am using ASP.NET with VB.NET. I have tried using the CSS "text-overflow: ellipsis" method as well, but I had some table formatting issues that I have not resolved.
Is there a way to handle these NULL values and prevent run-time exceptions?
Thanks!
One problem you are having is that the old IIF is a function which evaluates all the parts before it decides what to return.
IIF(Not IsDBNull(Item.LabelDescription), TruePart, FalsePart)
It does not matter if the expression is true or not, the TruePart and
FalsePart statements will always be executed. Since they include references to something which may be DBNull/Nothing/null, you get an error.
Something else though is that Nothing is not the same as DBNull, and if Item is an Object which can be Nothing/null, then testing the description of Nothing/null will be problematic.
The If Operator has been available since abut 2008. The structure is the same but it only evaluates the test condition and the True or False expression which applies:
If( Condition, TruePart, FalsePart )
The "short circuiting" prevents the expression/Part which does not apply from being evaluated. As long as the rest of the code is valid, you should be able to just clip one of the Is from the IIF functions.
Since you want to the object Nothing I would use the Nothing keyword rather than the VB IsNothing function:
If(Item IsNot Nothing),
If(Item.LabelDescription.ToString.Length > 30, x, y), y)
The If operator is not the same as the If/Then/Else statement block.

How to use webdings character map in asp.net

I want to use webdings characters in .net application.
Does anyone know how to do this.
I tried using :
ASPX:
<asp:Label ID="lblSample" runat="server" Font-Names="Webdings" ></asp:Label>
CODE BEHIND:
lblSample.Text = "0x61"
But it doesn't displaying properly.
As can be seen in any ASCII table, character 0x61 is a lower case a.
You are trying to output the string "0x61" instead of a lower case a.
You should be doing this:
lblSample.Text = "a"

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 !=

Best Technique for Multiple Eval Fields in Gridview ItemTemplate?

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.

Resources