Results 1 to 24 of 24

Thread: Programatically use a DataBound <%# ... %> variable?

  1. #1

    Thread Starter
    Retired VBF Adm1nistrator plenderj's Avatar
    Join Date
    Jan 2001
    Location
    Dublin, Ireland
    Posts
    10,359

    Programatically use a DataBound <%# ... %> variable?

    Urgh. Right. This is basically what I want to do:

    VB Code:
    1. <%# If Not Container.DataItem("strImagePath") = vbNullString Then %>
    2.     <img src="<%# Container.DataItem("strImagePath") %>" />
    3. <% Else %>
    4.     &nbsp;
    5. <% End If %>

    No combinatio of that seems to work
    Microsoft MVP : Visual Developer - Visual Basic [2004-2005]

  2. #2

  3. #3

    Thread Starter
    Retired VBF Adm1nistrator plenderj's Avatar
    Join Date
    Jan 2001
    Location
    Dublin, Ireland
    Posts
    10,359
    Blergh?

    Basically right, if I have a Repeater or thingie like that, I want to be able to display some fields and maybe not others depending on their content.

    So one cell in the table im using is to display an image, but not every record has an image. I don't want to include a path to some blank gif file, I'd prefer to leave that field empty in the DB.
    So if I have this code:

    VB Code:
    1. <img src="<%# Container.DataItem("strImagePath") %>">

    That works perfectly... provided there is actually some data in that column. But if its blank, I get a red x symbol for the image tag. So if there's data in that column, display the image, otherwise just a non breaking space.....
    Microsoft MVP : Visual Developer - Visual Basic [2004-2005]

  4. #4
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632
    What you need to do is use:
    VB Code:
    1. Private Sub Repeater1_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles Repeater1.ItemCreated
    2.  
    3. End Sub
    Using e what you would do is make the image invisible if the databound value is nullstring.

    Make sense?

    Not good enough at .NET to give you an example, but that is definately the way to go.

    Does that help?

    Woka

  5. #5
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632
    OK, I am good enough to give you an example...I think
    VB Code:
    1. Private Sub Repeater1_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles Repeater1.ItemCreated
    2.     Dim MyImage As System.Web.ui.webcontrols.Image
    3.     Select Case e.Item.ItemType
    4.         Case ListItemType.Item, ListItemType.AlternatingItem
    5.             MyImage = CType(e.Item.FindControl("imgPic"), System.Web.ui.webcontrols.Image)
    6.             If MyImage.ImageUrl.Length = 0 Then
    7.                 MyImage.Visible = False
    8.             End If
    9.     End Select
    10. End Sub
    Is that what you want?

    Woka

  6. #6
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704
    Along the lines of what woka said (sorry woka you missed one thing - the datarecord)


    VB Code:
    1. 'ItemCreated is called each time the datalist is rendered.
    2.     'ItemDataBound is called only when the data is bound
    3.     'use ItemDatabound if you enable viewstate for the page
    4.     'otherwise on each render ItemCreated duplicates unnecessary steps
    5.     Private Sub DataList1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs) _
    6. Handles DataList1.ItemDataBound
    7.         If e.Item.ItemType = ListItemType.AlternatingItem OrElse e.Item.ItemType = ListItemType.Item Then
    8.             'use dbdatarecord if binding to datareader, datarowview for datatable
    9.             Dim dbr As System.Data.Common.DbDataRecord = DirectCast(e.Item.DataItem, Data.Common.DbDataRecord)
    10.             'if column 1 (you could use dbr("imageurl") to access) is empty string
    11.             If DirectCast(dbr(1), String) = String.Empty Then
    12.                 'cast the control, you can use findcontrol like woka did
    13.                 'or just bind the control dependant on its location
    14.                 '(starts at 1 and continues with odd numbers, so the 2nd control
    15.                 'would be accessed by e.item.controls(3)
    16.                 DirectCast(e.Item.Controls(1), System.Web.UI.WebControls.Image).Visible = False
    17.  
    18.             End If
    19.         End If
    20.     End Sub

    in your aspx you would simply have
    <asp:repeater>
    <ItemTemplate>
    <asp:image runat="server" ></asp:image>
    </ItemTemplate>
    </asp:repeater>

    This actually is how I develop apps, which allows for
    cleaner front side code and seperates appearance from logic.
    Last edited by nemaroller; Oct 27th, 2004 at 06:54 AM.

  7. #7

  8. #8

    Thread Starter
    Retired VBF Adm1nistrator plenderj's Avatar
    Join Date
    Jan 2001
    Location
    Dublin, Ireland
    Posts
    10,359
    Ahhhh thank-you guys. Never thought about that
    Microsoft MVP : Visual Developer - Visual Basic [2004-2005]

  9. #9

  10. #10

    Thread Starter
    Retired VBF Adm1nistrator plenderj's Avatar
    Join Date
    Jan 2001
    Location
    Dublin, Ireland
    Posts
    10,359
    Hmmm.

    VB Code:
    1. Private Sub rptSales_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs) Handles rptSales.ItemDataBound
    2.         If e.Item.ItemType = ListItemType.AlternatingItem OrElse e.Item.ItemType = ListItemType.Item Then                        
    3. [b]            If DirectCast(e.Item.DataItem("strImagePath"), String) = String.Empty Then[/b]
    4.                 Response.Write("nothing")
    5.             Else
    6.                 Dim x As New System.Web.UI.WebControls.Image
    7.                 x.ImageUrl = e.Item.DataItem("strImagePath")
    8.                 x.Visible = True
    9.             End If
    10.         End If
    11.     End Sub
    12. End Class

    produces

    Code:
    Line 110:        If e.Item.ItemType = ListItemType.AlternatingItem OrElse e.Item.ItemType = ListItemType.Item Then            
    Line 111:            'Dim dbr As System.Data.Common.DbDataRecord = DirectCast(e.Item.DataItem, Data.Common.DbDataRecord)                        
    Line 112:            If DirectCast(e.Item.DataItem("strImagePath"), String) = String.Empty Then
    Line 113:                Response.Write("nothing")
    Line 114:            Else
    Microsoft MVP : Visual Developer - Visual Basic [2004-2005]

  11. #11
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704
    I assume you are getting an error?

    The only issue I see is if your that data item is null. So you would check for dbnull first, depending if your pulling from a proc or what not.
    VB Code:
    1. If not dbr("strImagePath") is Dbnull.Value Then

  12. #12

    Thread Starter
    Retired VBF Adm1nistrator plenderj's Avatar
    Join Date
    Jan 2001
    Location
    Dublin, Ireland
    Posts
    10,359
    Duh sorry never posted the error




    Server Error in '/Gaffs.ie' Application.
    --------------------------------------------------------------------------------

    Specified cast is not valid.
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.InvalidCastException: Specified cast is not valid.

    Source Error:

    Line 109: Private Sub rptSales_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs) Handles rptSales.ItemDataBound
    Line 110: If e.Item.ItemType = ListItemType.AlternatingItem OrElse e.Item.ItemType = ListItemType.Item Then
    Line 111: If DirectCast(e.Item.DataItem("strImagePath"), String) = String.Empty Then
    Line 112: Response.Write("nothing")
    Line 113: Else


    Source File: C:\Inetpub\wwwroot\Gaffs.ie\uctl\SalesRepeater.ascx.vb Line: 111

    Stack Trace:

    [InvalidCastException: Specified cast is not valid.]
    Gaffs.ie.SalesRepeater.rptSales_ItemDataBound(Object sender, DataListItemEventArgs e) in C:\Inetpub\wwwroot\Gaffs.ie\uctl\SalesRepeater.ascx.vb:111
    System.Web.UI.WebControls.DataList.OnItemDataBound(DataListItemEventArgs e) +109
    System.Web.UI.WebControls.DataList.CreateItem(Int32 itemIndex, ListItemType itemType, Boolean dataBind, Object dataItem) +139
    System.Web.UI.WebControls.DataList.CreateControlHierarchy(Boolean useDataSource) +689
    System.Web.UI.WebControls.BaseDataList.OnDataBinding(EventArgs e) +49
    System.Web.UI.WebControls.BaseDataList.DataBind() +23
    Gaffs.ie.SalesRepeater.Page_Load(Object sender, EventArgs e) in C:\Inetpub\wwwroot\Gaffs.ie\uctl\SalesRepeater.ascx.vb:75
    System.Web.UI.Control.OnLoad(EventArgs e) +67
    System.Web.UI.Control.LoadRecursive() +35
    System.Web.UI.Control.LoadRecursive() +98
    System.Web.UI.Page.ProcessRequestMain() +750




    --------------------------------------------------------------------------------
    Version Information: Microsoft .NET Framework Version:1.1.4322.2032; ASP.NET Version:1.1.4322.2032
    Attached Files Attached Files
    Microsoft MVP : Visual Developer - Visual Basic [2004-2005]

  13. #13
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704
    Well, I never tried accessing the data directly from e.data.dataitem.

    That is property returns an object more than likely, and so I always cast it to either a dbDataRecord or DataRowView first.
    VB Code:
    1. Dim dbr as System.Data.Common.DbDataRecord = DirectCast(e.Item.DataItem, System.Data.Common.DbDataRecord)
    2.  
    3. If Not dbr("strImpagePath") is DbNull.Value Then
    4. If dbr("strImagePath") = String.Empty Then
    5. ...
    6. End If
    7. End If

  14. #14

    Thread Starter
    Retired VBF Adm1nistrator plenderj's Avatar
    Join Date
    Jan 2001
    Location
    Dublin, Ireland
    Posts
    10,359
    Argh this is driving me mad
    Microsoft MVP : Visual Developer - Visual Basic [2004-2005]

  15. #15
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704
    Put a breakpoint there... see what the object contains...

  16. #16

    Thread Starter
    Retired VBF Adm1nistrator plenderj's Avatar
    Join Date
    Jan 2001
    Location
    Dublin, Ireland
    Posts
    10,359
    The object's a null reference. I haven't sat down to tackle this problem for more than 5 minutes at a time over the past week. I'll give it a proper looking at tomorrow morning
    Microsoft MVP : Visual Developer - Visual Basic [2004-2005]

  17. #17
    Hyperactive Member
    Join Date
    Dec 2001
    Location
    Dublin, Ireland
    Posts
    262
    If this is Sql Server then you may be allowing nulls in that field. If so use the t-sql function isnull when selecting data. e.g. select isnull(strImpagePath, ''), etc.
    This will ensure that if it's null it will return an empty string instead. Also it's probably not a good idea to have an asp.net image control on every line unless you set enableviewstate=false. Otherwise even the invisible controls will be stored in the viewstate. Another option I recommend is to use a public function in your code behind to accept the strImpagePath value and return either an image or nothing:-

    public function GetImage(imagepath as string) as string
    if imagepath.length=0 then
    return ""
    else
    return "<img src=""" & imagepath & """>"
    end if
    end function

    Then in your html use the following:-

    <%# GetImage(Container.DataItem("strImagePath")) %>

  18. #18
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704
    Musician,

    You bring up a good point on not using an asp image control, a simple html img tag with a runat=server attribute will suffice.

    But I disagree with your statement of using late-binding (aka implicit conversion) means of Container.DataItem to accept a image path by means of a openly public statement through the code behind. Several reasons:

    1) Performance hit - while not drastic, if you had 100+ images, the binding statement as provided by using the <% %> binding tags will stifle performance on the server. There's a large degree of implicit type casting occuring here.

    2) Having an openly accessible function in the assembly when it does not need to be is opening a channel for misuse, malicious or not. At worst, it should be declared Protected.

    3) Incorporating <% %> tags does not foster cleanly seperating content from the code-logic. This throwsback to old style ASP coding. I think you'll agree that if you had 5 or 6 controls in one databound item in a data template control, the front side aspx looks messy as sin. Many tutorials for teaching asp.net use this method only for simplicity sake.

    4) Functionality ... what if there was a textbox that needed to have a red background color when its text property was empty, and default to a '<no value>' text setting? Using code-behind binding allows for cleaner manipulation of the control:
    VB Code:
    1. If dbr("textboxText") Is Dbnull.Value Then myTextBox.BackColor=Color.Red
    2. myTextBox.BackColor="<no value>"
    3. End If


    Plenderj simply has to test for a DbNull.Value before attempting to assign the data. Or, if he incorporates the proc change you mentioned, then test for String.Empty.
    Last edited by nemaroller; Nov 7th, 2004 at 10:41 AM.

  19. #19
    Hyperactive Member
    Join Date
    Dec 2001
    Location
    Dublin, Ireland
    Posts
    262
    Quite right. Allow me to refer to it as an example for simplicity's sake.

  20. #20

    Thread Starter
    Retired VBF Adm1nistrator plenderj's Avatar
    Join Date
    Jan 2001
    Location
    Dublin, Ireland
    Posts
    10,359
    Finally working. Thanks guys

    Code:
    <td vAlign="top" align="middle" width="170">
    	<a style="color: #0000dd" href="#">
    		<%# GetImage(Container.DataItem(20)) %>
    	</a>
    </td>
    VB Code:
    1. Public Function GetImage(ByVal objImage As Object) As String
    2.         Dim strRetVal As String, strImage As String
    3.         If Not objImage Is Nothing Then
    4.             Try
    5.                 strImage = CType(objImage, String)
    6.                 If Not strImage = vbNullString Then
    7.                     strRetVal = "<img src=" & Chr(34)
    8.                     strRetVal &= strImage & Chr(34)
    9.                     strRetVal &= " />"
    10.                 End If
    11.             Catch ex As Exception
    12.                 strImage = vbNullString : strRetVal = vbNullString
    13.                 GoTo eof
    14.             End Try
    15.         Else
    16.             strRetVal = "nothing"
    17.         End If
    18. eof:
    19.         Return strRetVal
    20.     End Function

    yipeeeeeeeeeeeeee
    Microsoft MVP : Visual Developer - Visual Basic [2004-2005]

  21. #21
    Hyperactive Member
    Join Date
    Dec 2001
    Location
    Dublin, Ireland
    Posts
    262
    I'm gald you got it working but I would recommend you take nemaroller's points into consideration. It might be worth trying to do it in the code behind itemdatabound event instead of taking the performance hit of the method above.

  22. #22

    Thread Starter
    Retired VBF Adm1nistrator plenderj's Avatar
    Join Date
    Jan 2001
    Location
    Dublin, Ireland
    Posts
    10,359
    Well I've since implemented it as a user control, and am not using viewstate, so seems to be running quite swimmingly
    Microsoft MVP : Visual Developer - Visual Basic [2004-2005]

  23. #23

  24. #24

    Thread Starter
    Retired VBF Adm1nistrator plenderj's Avatar
    Join Date
    Jan 2001
    Location
    Dublin, Ireland
    Posts
    10,359
    Yeah I'm getting surprisingly good at this kind of thing now. I have some beautiful looking repeaters now. Took me a while to cop it.
    Going to dinner in my mother's tonight and perhaps cinema, but I can send you over some code for it later k?

    Basically what I do is create a template in dreamweaver or frontpage, then replace the real data with some placeholders, convert the placeholders into proper asp tags, and copy and paste that into the design view of the page
    Microsoft MVP : Visual Developer - Visual Basic [2004-2005]

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width