ASP.NET nested ListView using CSLADataSource

ASP.NET nested ListView using CSLADataSource

Old forum URL: forums.lhotka.net/forums/t/7485.aspx


uwillmore posted on Wednesday, August 19, 2009

Hi all!

I have been struggling with this all day and hope you can help me.

I have a nested ListView control on my ASP.NET page and I am trying to load it with a CSLADataSource. The datasource for the outer listView contains the datasource for the inner listView. My outer list is just a list of orders that contains a list of orderItems. Here are the definitions for the lists.

OrderGroupList : ReadOnlyListBase<OrderGroupList,OrderGroupInfo>

OrdergroupInfo is the object that contains the data for each orderGroup and it is defined like this:

OrderGroupInfo : ReadOnlyBase<OrderGroupInfo>

OrderGroupInfo contains 5 properties on of which is another list: The list of orderItems. This list is defined very similarly:

OrderItemList : ReadOnlyListBase<OrderItemList, OrderItemInfo>

and it contains a read-only base object that holds the data for each order item.

OrderItemInfo : ReadOnlyBase<OrderItemInfo>

Of course OrderItemInfo has several properties but I don't think I need to list them to make my point. Anyone familiar with CSLA should recognize what I have outlined so far, I think. So I want to display the nested read-only Lists on an ASP.NET page using nested ListView controls. The code for the listView looks something like this:

I start the outer list, using a csla DataSource to set the DataSourceID.

<asp:ListView ID="OrderGroupListView" ItemPlaceholderID="OrderGroupItem" runat="server" DataSourceID="OrderGroupsCSLADataSource">

<LayoutTemplate>

<asp:PlaceHolder runat="server" ID="OrderGroupItem" />

</LayoutTemplate>

<ItemTemplate>

<asp:Label ID="OrderGroupIDLabel" runat="server" Visible="false" Text='<%# Eval("OrderGroupID") %>' />

<asp:Label ID="GroupTypeIDLabel" runat="server" Visible="false" Text='<%# Eval("GroupTypeID") %>' />

<table class="dataTable">

<tr class="dataTable">

<th style="Width:15%">

<nobr>Order Group:</nobr>

</th>

<td>

<asp:Label ID="GroupTypeLabel" runat="server" Text='<%# Eval("GroupType") %>' />

</td>

</tr>

<tr>

<td colspan="2">

Now before I close the ItemTemplate for the outer list, I start my OrderItems list definition.

         <asp:ListView ID="OrderItemListView" ItemPlaceholderID="OrderItem" runat="server" DataSourceID="???">    

         <LayoutTemplate>

         <table id="itemPlaceholderContainer" runat="server" class="dataTable">

         <tr runat="server" style="" class="dataTable">

         <th runat="server">

         <nobr>Quantity</nobr>

         </th>

........ And so on,

         <tr id="OrderItem" runat="server" class="dataTable">

         </tr>

         </table>

         </LayoutTemplate>

         <ItemTemplate>         

            <tr class="dataTableAlt">

            <td>

               <asp:Label ID="QuantityLabel" runat="server" Text='<%# Eval("OrderItemList.Quantity") %>' />

               </td>

  ....... and so on, until we get to the end of the inner list

                </ItemTemplate>

         </asp:ListView>

....... but we still need to finish the outer list's template

         </td>

         </tr>

         </table>

      </ItemTemplate>

</asp:ListView>

So the inner list is defined within the item templare of the outer list, really very similar to how the list objects are defined.

And now come my questions:

What do I assign as the DataSourceID for the inner list? I have tried

DataSourceID = OrderGroupsCSLADataSource.OrderItemsList

but the compiler does not like that. I have tried using

DataSourceID = OrderGroupsCSLADataSource

and then use

Eval ("OrderItemList.Quantity")

in the template but again the compiler complains.

Of course I would also like to know what the eval call for the templates should look like when I display the data, though I think that will be obvious once I understand what I need to assign to the inner lists dataSourceID.

I have tried using 2 different datasources one for the outer list and one for the inner list, but then I can only get the list to display once. After that, the page never gets refreshed no matter what I do. It finally occured to me that I will have to determine in code which OrderItemList to bind to each inner list, if I use 2 data sources because the .NET framework won't know that there is any relationship between the 2 datasources. I really don't want to do this in code, when I should be able to do this with just one datasource and let the framework handle the rest.

I even went as far as using a SQLDataSource at one time to see if that would work and sure enough, it does. I used the same stored procedure for the SQLDatasource as I use for the CSLA DataSource and the lists displayed just as I wanted them too: Each Order was listed with it's list of order items, before the next Order was listed. That implies that the .NET Framework knows how to handle the nested list if the data bound to the list is nested in the same way. Alas, an SQLDataSource is not what I want to use. Our standards demand we use CSLA DataSOurces whenever possible.

Does anyone here know how to do this using a single CSLA DataSource?

 Thanks a bunch for any help you can give me. If you want the complete source code for the ASP page, email me and I will send it to you. It's too lengthy to post.  

TIA

URW

xAvailx replied on Thursday, August 20, 2009

I've done this in the past with CSLA classes, but not with the csladatasource. I bind the listview datasource directly to the readonlylist.

For the nested data source, try the following syntax:

DataSource='&lt;%# Eval(&quot;ChildPropertyContainingList&quot;) %&gt;'

Then for the items to be bound in the nested source, you can just use the property of the info class.

e.g.

&lt;%# Eval(&quot;InfoProperty&quot;) %&gt;

HTH

Sorry, can't get the code to format correctly...

uwillmore replied on Thursday, August 20, 2009

I figured it out about 30 minutes before your email arrived!

I ended up assigning the child data list to the DataSource (not the DataSourceID) of the inner ListView almost exactly like you suggest. Since my child data list is a property of the DataSource for the outer list, I can not assign the inner data source exactly as you suggest  and thus the syntax I used looks something like this:

DataSource = '<%#Eval ("OuterDataSource.InnerItemsList")%>'

(I can't get the formatting to look right either.)

The code for displaying the properties in InnerItemsList looks exactly like you show in your reply.

I found a pretty good example for nested listViews and other controls that can be nested in an article from the online version of MSDN Magazine. If you are interested you can read the article here:

http://msdn.microsoft.com/en-us/magazine/cc500643.aspx

I want to thank you for taking the time to post your answer. I really appreciate that, and hope I can return the favor one day.

Again, thanks for your reply

Sincerely

URW

Copyright (c) Marimer LLC