I need to retrieve a set of Widgets from my data access layer, grouped by widget.Manufacturer, to display in a set of nested ASP.NET ListViews.
The problem is that (as far as I can tell) the nested ListView approach requires me to shape the data before using it, and I can't figure out the best approach to take. The best I've been able to come up with so far is to put a LINQ query in my data access layer like so:
var result = from widget in GetAllWidgets(int widgetTypeID)
group widget by widget.Manufacturer into groupedWidgets
let widgets = from widgetGroup in groupedWidgets
select widgetGroup
select new { Manufacturer = groupedWidgets.Key, Widgets = widgets };
Of course, anonymous types can't be passed around, so that doesn't work. Defining a custom class to enclose data seems like the wrong way to go. Is there some way I can perform the grouping on the ASP.NET side of things? I'm using ObjectDataSources to access the DAL.
Updated: OK, I'm not creating an anonymous type anymore, and instead my DAL passes an IEnumerable<IGrouping<Manufacturer, Widget>>
to the ASP.NET page, but how can I use this in my ListViews? I need to render the following HTML (or something pretty much like it)
<ul>
<li>Foo Corp.
<ol>
<li>Baz</li>
<li>Quux</li>
</ol>
</li>
<li>Bar Corp.
<ol>
<li>Thinger</li>
<li>Whatsit</li>
</ol>
</li>
</ul>
Originally, I had a ListView within a ListView like so:
<asp:ListView ID="ManufacturerListView">
<LayoutTemplate>
<ul>
<asp:Placeholder ID="itemPlaceholder" runat="server" />
</ul>
</LayoutTemplate>
<ItemTemplate>
<li><asp:Label Text='<%# Eval("Manufacturer.Name") %>' />
<li>
<asp:ListView ID="WidgetsListView" runat="server" DataSource='<%# Eval("Widgets") %>'>
<LayoutTemplate>
<ol>
<asp:PlaceHolder runat="server" ID="itemPlaceholder" />
</ol>
</LayoutTemplate>
<ItemTemplate>
<li><asp:Label Text='<%# Eval("Name") %>'></li>
</ItemTemplate>
</asp:ListView>
</li>
</ItemTemplate>
</asp:ListView>
Note how the DataSource
property of WidgetsListView is itself databound. How can I duplicate this functionality without reshaping the data?
This is getting kind of complicated, sorry if I should have just made a separate question instead.
Ok, I'm going to contradict my prior statement. Since eval wants some kind of property name in the nested control, we should probably shape that data.
public class CustomGroup<TKey, TValue>
{
public TKey Key {get;set;}
public IEnumerable<TValue> Values {get;set;}
}
// and use it thusly...
IEnumerable<CustomGroup<Manufacturer, Widget>> result =
GetAllWidgets(widgetTypeId)
.GroupBy(w => w.Manufacturer)
.Select(g => new CustomGroup<Manufacturer, Widget>(){Key = g.Key, Values = g};
/// and even later...
<asp:ListView ID="ManufacturerListView">
<LayoutTemplate>
<ul>
<asp:Placeholder ID="itemPlaceholder" runat="server" />
</ul>
</LayoutTemplate>
<ItemTemplate>
<li><asp:Label Text='<%# Eval("Key.Name") %>' />
<li>
<asp:ListView ID="WidgetsListView" runat="server" DataSource='<%# Eval("Values") %>'>
<LayoutTemplate>
<ol>
<asp:PlaceHolder runat="server" ID="itemPlaceholder" />
</ol>
</LayoutTemplate>
<ItemTemplate>
<li><asp:Label Text='<%# Eval("Name") %>'></li>
</ItemTemplate>
</asp:ListView>
</li>
</ItemTemplate>
</asp:ListView>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With