Link to home
Start Free TrialLog in
Avatar of attipa
attipaFlag for United States of America

asked on

Obtaining item specific data in a datalist

Hello,

I am trying to get this to work and want to know if it is possible.  I have a table called Store.  In the table, I have columns that not all of the rows have to use.  For example, the Address2 column is only used if the address of the store needs a second line.  I am creating a datalist to display all stores in the state of CA.  Some of the stores contain the Address2 column.  In easier words, if I have 10 items in the datalist, I want 6 of them to call the data from Address2 column.  How can I control each item individually?  Is there any way I can call the data in the code behind file?  How can I call it only when I need it?  The code is below:


aspx file
----------------------------------
<asp:DataList ID="Retailers" Runat="server" RepeatColumns="2" RepeatDirection="Horizontal" HorizontalAlign="Left">
      <ItemTemplate>
            <table width="180" border="0" cellpadding="0" cellspacing="0">
                  <tr>                                                                                                <td align="left" valign="top">                                                                                    <font class="RetailerTitle">                                                                                    <%# Container.DataItem("Name") %><br>                                                                  </font><font class="RetailerAddress">                                                                                                   <%# Container.DataItem("Address1") %><br>                                                            </font><font class="RetailerAddress">
                              <%# Container.DataItem("City") %>
                              <%# Container.DataItem("State") %>
                              <%# Container.DataItem("PostalCode") %><br>
                        </font><font class="RetailerAddress">
                              <%# Container.DataItem("Telephone") %><br>
                                                      <br>
                        </font>
                  </td></tr>
            </table>
      </ItemTemplate>
</datalist>




aspx.vb file
------------------------------------
If location = "CA" Then
  LocationLabel.Text = "California"

  Dim store As New StoreManager
  Dim reader As SqlDataReader
  reader = store.GetStoresByState("CA")
  Retailers.DataSource = reader.Read()
  Retailers.DataKeyField = "StoreID"

  Retailers.DataBind()
End If
Avatar of mmarinov
mmarinov

Hi attipa,

there is an event ItemDataBound to work with data in DataList before show it to the user
DataList.ItemDataBound Event: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwebuiwebcontrolsdatalistclassitemdataboundtopic.asp

Regards!
B..M
mmarinov
Avatar of attipa

ASKER

Hi,

Thanks for the response.  I read the entire topic and I am even more confused on what to do.  Is there anyway you can incorporate it into the code I provided before.  I would really appreciate it.  The thing I am trying to do is on the top code where it says..........

<%# Container.DataItem("Address1") %>

If there is something in the Address2 Column of the table for that specific item
     Add  <%# Container.DataItem("Address2") %><br>
End If

Any help is greatly appreciated.
Avatar of attipa

ASKER

Can someone please help me...I really have to get this project done soon.  Thanks a million in advance.
The easiest way is to have your item template always include the Address2 info, but make it invisible if there is no data. After you associate the ItemDataBound event handler with the control, it would go something like this:

Sub Item_Bound(sender As Object, e As DataListItemEventArgs)

         If e.Item.ItemType = ListItemType.Item Or _
             e.Item.ItemType = ListItemType.AlternatingItem Then

            If (CType(e.Item.DataItem, DataRowView)).Row.ItemArray(2) = System.DbNull.Value
                ' Retrieve a Label control in the current DataListItem.
                Dim lblAddress2 As Label = _
                    CType(e.Item.FindControl("Address2"), Label)

                lblAddress2.Visible = false
            End If

         End If

      End Sub
<asp:DataList ID="Retailers" Runat="server" RepeatColumns="2" RepeatDirection="Horizontal" HorizontalAlign="Left" OnItemDataBound="Item_Bound">
     <ItemTemplate>
          <table width="180" border="0" cellpadding="0" cellspacing="0">
                <tr>                                                                                <td align="left" valign="top">                                                                      <font class="RetailerTitle">                                                                      <%# Container.DataItem("Name") %><br>                                                       </font><font class="RetailerAddress">                                                                                        <asp:Label id="lblAddr1" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Address1") %>' />
<br>                                                  </font>
<asp:Label id="lblAddr2" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Address2") %>' />

<font class="RetailerAddress">
                         <%# Container.DataItem("City") %>
                         <%# Container.DataItem("State") %>
                         <%# Container.DataItem("PostalCode") %><br>
                    </font><font class="RetailerAddress">
                         <%# Container.DataItem("Telephone") %><br>
                                             <br>
                    </font>
               </td></tr>
          </table>
     </ItemTemplate>
</datalist>

create itemdatabound event

Sub Item_Bound(sender As Object, e As RepeatertemEventArgs)

         If e.Item.ItemType = ListItemType.Item Or _
             e.Item.ItemType = ListItemType.AlternatingItem Then


            ' Retrieve the Label control in the current DataListItem.
            Dim addr1 As Label = _
                CType(e.Item.FindControl("lblAddr1"), Label)

            Dim addr2 As Label = _
                CType(e.Item.FindControl("lblAddr2"), Label)

            if Not addr1.Text = String.Empty Then
               addr2.Visible = True
            else
               addr2.Visible = False
            End If
           
         End If

      End Sub


B..M
mmarinov
Avatar of attipa

ASKER

Okay.....I got that portion working.  Thanks a million mmarinov.  Now, I have pasted my code below, it will only work for one database row.  When there is two or more, it won't work.  Here is what I have..........

.aspx page
----------------------------------------------
<asp:datalist id="Retailers" OnItemDataBound="Item_Bound" HorizontalAlign="Left" RepeatDirection="Horizontal"
                        RepeatColumns="2" Runat="server">
                        <ItemTemplate>
                              <table width="180" border="0" cellpadding="0" cellspacing="0">
                                    <tr>
                                          <td align="left" valign="top">
                                                <font class="RetailerTitle">
                                                      <asp:Label ID="StoreName" Runat="server" CssClass="RetailerTitle" Visible="True"></asp:Label><br>                                                      
                                                </font>
                                                <font class="RetailerSubTitle">
                                                      <asp:Label ID="StoreLocation" Runat="server" CssClass="RetailerSubTitle" Visible="True"></asp:Label>
                                                </font>
                                                <font class="RetailerAddress">
                                                      <asp:Label ID="StoreInformation" Runat="server" CssClass="RetailerAddress" Visible="True"></asp:Label>
                                                </font><font class="RetailerAddress">
                                                      <br>
                                                      <br>
                                                </font>
                                          </td>
                                    </tr>
                              </table>
                        </ItemTemplate>
                        <SeparatorTemplate>
                              <table width="20" cellpadding="0" cellspacing="0" border="0">
                                    <tr>
                                          <td align="center" valign="top">
                                          </td>
                                    </tr>
                              </table>
                        </SeparatorTemplate>
                  </asp:datalist>





.aspx.vb file (code-behind)
---------------------------------------------------------------------------
    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim location As String = Request.Params("Location")
        AddHandler Retailers.ItemDataBound, AddressOf Item_Bound

        If Not Page.IsPostBack Then

            If location = "" Then
                Response.Redirect("store-locator.aspx")
            ElseIf location = "CA" Then

                Retailers.DataSource = CreateDataSource()
                Retailers.DataBind()

            End If
        End If

    End Sub

    Public Function CreateDataSource() As ICollection
        Dim dt As DataTable = New DataTable
        Dim dr As DataRow

        Dim location As String = Request.Params("Location")
        Dim store As New StoreManager
        Dim reader As SqlDataReader
        reader = store.GetStoresByState("CA")

        dt.Columns.Add(New DataColumn("Name", GetType(String)))
        dt.Columns.Add(New DataColumn("Location", GetType(String)))
        dt.Columns.Add(New DataColumn("Address1", GetType(String)))
        dt.Columns.Add(New DataColumn("Address2", GetType(String)))
        dt.Columns.Add(New DataColumn("City", GetType(String)))
        dt.Columns.Add(New DataColumn("State", GetType(String)))
        dt.Columns.Add(New DataColumn("PostalCode", GetType(String)))
        dt.Columns.Add(New DataColumn("Telephone", GetType(String)))
        dt.Columns.Add(New DataColumn("Website", GetType(String)))

        Dim i As Integer
        reader.Read()
                                                                  <--------------------------SOMETHING HAS TO BE ENTERED HERE...I THINK...
 
        For i = 0 To 0           <---------------I PUT A ZERO HERE JUST SO IT DOES IT ONCE...I TRIED A WHILE LOOP
                                        <------------------WITH COUNT AND READER.READ() AND IT DIDNT WORK
            dr = dt.NewRow()

            dr(0) = reader("Name").ToString()
            dr(1) = reader("Location").ToString()
            dr(2) = reader("Address1").ToString()
            dr(3) = reader("Address2").ToString()
            dr(4) = reader("City").ToString()
            dr(5) = reader("State").ToString()
            dr(6) = reader("PostalCode").ToString()
            dr(7) = reader("Telephone").ToString()
            dr(8) = reader("Website").ToString()

            dt.Rows.Add(dr)

        Next i

        Dim dv As DataView = New DataView(dt)
        Return dv

    End Function

    Public Sub Item_Bound(ByVal sender As Object, ByVal e As DataListItemEventArgs)

        If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then

            Dim StoreName As Label = CType(e.Item.FindControl("StoreName"), Label)
            Dim StoreLocation As Label = CType(e.Item.FindControl("StoreLocation"), Label)
            Dim StoreInformation As Label = CType(e.Item.FindControl("StoreInformation"), Label)

            StoreName.Text = Convert.ToString((CType(e.Item.DataItem, DataRowView)).Row.ItemArray(0).ToString())

            Dim StoreLocationString As StringBuilder = New StringBuilder
            If Not (Convert.ToString((CType(e.Item.DataItem, DataRowView)).Row.ItemArray(1).ToString())) = "" Then
                StoreLocationString.Append(Convert.ToString((CType(e.Item.DataItem, DataRowView)).Row.ItemArray(1).ToString()))
                StoreLocationString.Append("<br>")
            End If
            StoreLocation.Text = StoreLocationString.ToString()


            Dim StoreInformationString As StringBuilder = New StringBuilder
            StoreInformationString.Append(Convert.ToString((CType(e.Item.DataItem, DataRowView)).Row.ItemArray(2).ToString()))
            StoreInformationString.Append("<br>")
            If Not (Convert.ToString((CType(e.Item.DataItem, DataRowView)).Row.ItemArray(3).ToString())) = "" Then
                StoreInformationString.Append(Convert.ToString((CType(e.Item.DataItem, DataRowView)).Row.ItemArray(3).ToString()))
                StoreInformationString.Append("<br>")
            End If
            StoreInformationString.Append((CType(e.Item.DataItem, DataRowView)).Row.ItemArray(4).ToString())
            StoreInformationString.Append(" ")
            StoreInformationString.Append((CType(e.Item.DataItem, DataRowView)).Row.ItemArray(5).ToString())
            StoreInformationString.Append(" ")
            StoreInformationString.Append((CType(e.Item.DataItem, DataRowView)).Row.ItemArray(6).ToString())
            StoreInformationString.Append("<br>")
            If Not (Convert.ToString((CType(e.Item.DataItem, DataRowView)).Row.ItemArray(7).ToString())) = "" Then
                StoreInformationString.Append(Convert.ToString((CType(e.Item.DataItem, DataRowView)).Row.ItemArray(7).ToString()))
                StoreInformationString.Append("<br>")
            End If
            If Not (Convert.ToString((CType(e.Item.DataItem, DataRowView)).Row.ItemArray(8).ToString())) = "" Then
                StoreInformationString.Append(Convert.ToString((CType(e.Item.DataItem, DataRowView)).Row.ItemArray(8).ToString()))
                StoreInformationString.Append("<br>")
            End If
            StoreInformation.Text = StoreInformationString.ToString()
        End If

    End Sub
ASKER CERTIFIED SOLUTION
Avatar of mmarinov
mmarinov

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Wait, backup. You don't need to create a table via a SqlDataReader then bind to the table. Just bind directly to the reader: it's much better performing and simpler.

'initialize reader
myDataList.DataSource = reader
myDataList.DataBind()
Avatar of attipa

ASKER

thanks a milliom mmarinov
Hey! I also provided the specific implementation algorithm and a way for you to boost performance and throw away 30+ lines of useless overhead.

Somedays I just don't feel appreciated. ;-) I guess you can't please everyone.
Avatar of attipa

ASKER

Im sorry about the points, but you can not use that method if you are not implementing every column in every datalist entry.
No worries, though a thank you would have been nice. :-)

Actually since the processing happens in the ItemDataBound event, the methods are equivalent. You simply bind, then optionally set a control's visibility to false if a certain piece of data is blank/null. The nature of the DataSource is irrelevant. It could be a SqlDataReader or a DataTable (or something else).

In other words, whereas you're initializing a DataReader, using it to build a table, then binding to the table (letting ItemDataBound do its magic), you could have just bound directly to the DateReader for the same effect.