Sunday, March 11, 2012

zeroing out one asp:boundcolumn based on the value of another one.

I am looking at using an itemtemplate with some javascript on the TEXT property of an asp:label

<asp:LabelID="AMOUNT_LBL"runat="SERVER"Text='<%# DataBinder.Eval(Container.DataItem,"COLUMN1")%>'></asp:Label>

Trying to see how I would either point to a function that would load the value or perhaps incorporate a quick javascript in the Text='javascript: if(column3>0{Set Value to result from Databound Column 1} else { Set Value to {0:###,##0})'

I know the syntax is probably messed up but you get the idea on what I am trying to do.


I guess there is no way to do this cleanly or perhaps I posted it to the wrong forum.


Hi:

You can do this in ItemDataBound event handler (also use ItemTemplate). In that event handler, to find the control, try:

Label l=e.Item.FindControl("Label_ID") as Label;

to retrieve data, try:

DataRowView drv=e.Item.DataItem as DataRowView

if(drv!=null){

//from drv["field_name"] we can decide whether to assign 0 to l

}

Regards


Thanks for the answer, someone provided a quick solution but I would be interested in exploring this way of addressing the issue.

Would it be possible to provide a more layman friendly example?

The quick fix looks like this:

<asp:TemplateColumn>
<ItemTemplate>
<asp:LabelID="AMOUNT_LBL2"runat="server"Text='<%#IIF(CONVERT.ToInt32(Eval("COLUMN3"))=0,0,Eval("COLUMN1"))%>'></asp:Label>
</ItemTemplate>
</asp:TemplateColumn>

How would that translate into a codebehind function OnDataBinding or another appropriate event.


Hi:

We can either do this in inline code or in code behind. But when the logic becomes very complex it's difficult to write&read that inline code. To do the same thing in code behind, you can try this in ItemDataBound event handler:

Dim drv As DataRowView = TryCast(e.Item.DataItem, DataRowView)
If Not drv Is Nothing Then
Dim l As Label = TryCast(e.Item.FindControl("AMOUNT_LBL2"), Label)
If Not l Is Nothing Then
If Convert.ToInt32(drv("COLUMN3")) = 0 Then
l.Text = "0"
Else
l.Text = drv("COLUMN1").ToString()
End If
End If
End If

Regards


Allen Chen – MSFT:

Hi:

We can either do this in inline code or in code behind. But when the logic becomes very complex it's difficult to write&read that inline code. To do the same thing in code behind, you can try this in ItemDataBound event handler:

Dim drv As DataRowView = TryCast(e.Item.DataItem, DataRowView)
If Not drv Is Nothing Then
Dim l As Label = TryCast(e.Item.FindControl("AMOUNT_LBL2"), Label)
If Not l Is Nothing Then
If Convert.ToInt32(drv("COLUMN3")) = 0 Then
l.Text = "0"
Else
l.Text = drv("COLUMN1").ToString()
End If
End If
End If

Regards

Thanks, that is very good as well. I have found a different solution to the problem but I guess in the end the result is what counts unless you are having a major impact on performance or security of course.

Someone else provided several solutions to this as well the one I found most elegant was:

<asp:TemplateColumn>
<ItemTemplate>
********** Plain Jane, no Handling here *******************
<asp:LabelID="AMOUNT_LBL"runat="SERVER"Text='<%# DataBinder.Eval(Container.DataItem,"COLUMN1")%>'></asp:Label>
********** In Line code block here with IF statement **********
<asp:LabelID="AMOUNT_LBL2"runat="server"Text='<%#IIF(CONVERT.ToInt32(Eval("COLUMN3"))>0,0,Eval("COLUMN1"))%>'></asp:Label>
********* Function Call here returning a value ********************
<asp:LabelID="AMOUBT_LBL3"runat="server"Text='<%# checkValue(Eval("COLUMN3"), Eval("COLUMN1"))%>'></asp:Label>
</ItemTemplate>
</asp:TemplateColumn>

ProtectedFunction checkValue(ByVal valofcolumn3AsObject,ByVal valofcolumn1AsObject)As Int32
IfCType(valofcolumn3 > 0, Int32)Then
Return 0
Else
ReturnCType(valofcolumn1, Int32)
EndIf

EndFunction

From a strictly ASP.NET perspective which one is the most elegant and also the least significant impact on performance?


Hi:

I would suggest you to test the performance yourself. Simply add this global.asax file to your project:

<%@. Application Language="C#" %><script language="C#" runat=server>protected void Application_BeginRequest(object sender, EventArgs e){ this.Context.Items["startTime"] = DateTime.Now;}protected void Application_EndRequest(object sender, EventArgs e){ DateTime dt = (DateTime)this.Context.Items["startTime"]; TimeSpan ts = DateTime.Now - dt; this.Context.Response.Output.Write( "<br/><font size=1>request processing time: {0}</font>", ts);}</script>
Regards

That is an excellent Idea, I am certainly not agaisnt getting my elbows dirty ya know.

:)

No comments:

Post a Comment