Search code examples
asp.netvb.netdatasourcecode-behindbulletedlist

Datasource needed to link supplier with products for each supplier


We would like to display in a GridView suppliers and a bulleted list of the products for each of the products that are displayed.

For example:

Supplier One               Product A
                           Product B

Supplier Two               Product A
                           Product B
                           Product C

This is what the GridView looks like:

        <asp:GridView 
            ID="GridView1" 
            runat="server" 
            AutoGenerateColumns="False" 
            CssClass="DataWebControlStyle">

            <HeaderStyle CssClass="HeaderStyle" />

            <AlternatingRowStyle CssClass="AlternatingRowStyle" />

            <Columns>
                <asp:BoundField 
                    DataField="CompanyName" 
                    HeaderText="Supplier" />

                <asp:TemplateField HeaderText="Products">
                    <ItemTemplate>
                        <asp:BulletedList 
                            ID="BulletedList1" 
                            runat="server" 
                            DataSource='<%#  %>'
                            DataTextField="ProductName">
                        </asp:BulletedList>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>

This is the code-behind file that loads the data into the GridView:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    Dim suppliersAdapter As New SuppliersTableAdapter

    GridView1.DataSource = suppliersAdapter.GetSuppliers()
    GridView1.DataBind()
End Sub

Can you tell us what to place in the asp:BulletedList DataSouce so the products can also be shown?

* Update *

Thanks to everyone for the help. I removed the DataSource='<%# %>' line and here is the additional working coding now in place based on your help in the code-behind file.

Since I'm learning ASP.Net, I added a lot of comments in the code to help myself learn what's going on and what makes it tick. Please adjust the comments if I made a mistake in the comments.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    ' TableAdapter object.
    ' Provide communication between this application and the database.
    '-----------------------------------------------------------------
    Dim suppliersAdapter As New SuppliersTableAdapter

    ' Get the data from the TableAdapter into the GridView.
    '------------------------------------------------------
    GridView1.DataSource = suppliersAdapter.GetSuppliers()

    ' Display the result set from the TableAdapter in the GridView.
    '--------------------------------------------------------------
    GridView1.DataBind()
End Sub

Protected Sub GridView1_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound

    ' A GridView has DataRows, EmptyDataRows, Footers, Headers, Pagers, and Separators.
    ' The DataSource will be assigned to the BulletedList in this GridView only when the RowType is a DataRow.
    ' This will make sure the "Object reference not set to an instance of an object" error will not be thrown.
    '---------------------------------------------------------------------------------------------------------
    If e.Row.RowType = DataControlRowType.DataRow Then

        ' TableAdapter object.
        ' Provide communication between this application and the database.
        '-----------------------------------------------------------------
        Dim productsAdapter As New ProductsTableAdapter

        ' BulletedList object.
        ' This object is created from the BulletedList control in the aspx file for GridView 
        ' so it can be used to assign a DataSource to the BulletedList.
        '------------------------------------------------------------------------------------
        Dim BulletedList1 As BulletedList = DirectCast(e.Row.FindControl("BulletedList1"), BulletedList)

        ' Get the SupplierID into a variable for use as a parameter for the GetProductsBySupplierID method of the TableAdapter.
        '----------------------------------------------------------------------------------------------------------------------
        Dim supplier = DataBinder.Eval(e.Row.DataItem, "SupplierID")

        ' Get the data from the TableAdapter into the GridView.
        '------------------------------------------------------
        BulletedList1.DataSource = productsAdapter.GetProductsBySupplierID(supplier)

        ' Display the result set from the TableAdapter in the GridView.
        '--------------------------------------------------------------
        BulletedList1.DataBind()
    End If
End Sub

Solution

  • You have a different data source for each list.

    You could achieve what you what by setting the datasource on the BulletedList on RowDataBound event of the grid.

    Attach a RowDataBound event handler as follows:

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
       if (e.Row.RowType==DataControlRowType.DataRow) 
       {       
           BulletedList BulletedList1 = (BulletedList)e.Row.FindControl("BulletedList1"); 
           var supplier = DataBinder.Eval(e.Row.DataItem, "CompanyName");
           BulletedList1.DataSource = GetProductListForSupplier(supplier);
           BulletedList1.DataBind();
       }
    }