使用嵌套的ListView显示IGrouping <>

Bra*_*bby 10 linq asp.net listview

我需要从我的数据访问层检索一组Widgets,按widget.Manufacturer分组,以显示在一组嵌套的ASP.NET ListViews中.

问题是(据我所知)嵌套的ListView方法要求我在使用之前对数据进行整形,我无法找出最佳方法.到目前为止,我能够提出的最好的方法是在我的数据访问层中放置一个LINQ查询,如下所示:

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 };
Run Code Online (Sandbox Code Playgroud)

当然,匿名类型不能传递,因此不起作用.定义一个自定义类来封装数据似乎是错误的方法.有没有什么方法可以在ASP.NET方面执行分组?我正在使用ObjectDataSources来访问DAL.

更新:好的,我不再创建匿名类型,而是我的DAL传递IEnumerable<IGrouping<Manufacturer, Widget>>给ASP.NET页面,但是如何在ListViews中使用它?我需要渲染以下HTML(或者非常类似的东西)

<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>
Run Code Online (Sandbox Code Playgroud)

最初,我在ListView中有一个ListView,如下所示:

<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>
Run Code Online (Sandbox Code Playgroud)

注意DataSourceWidgetsListView 的属性本身是如何数据绑定的.如何在不重塑数据的情况下复制此功能?

这有点复杂,对不起,如果我应该刚刚提出一个单独的问题.

Amy*_*y B 12

好吧,我要反驳我之前的陈述.由于eval在嵌套控件中需要某种属性名称,因此我们应该对该数据进行整形.

public class CustomGroup<TKey, TValue>
{
  public TKey Key {get;set;}
  public IEnumerable<TValue> Values {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

//并因此使用它......

IEnumerable<CustomGroup<Manufacturer, Widget>> result =
  GetAllWidgets(widgetTypeId)
  .GroupBy(w => w.Manufacturer)
  .Select(g => new CustomGroup<Manufacturer, Widget>(){Key = g.Key, Values = g};
Run Code Online (Sandbox Code Playgroud)

///甚至更晚......

<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>
Run Code Online (Sandbox Code Playgroud)


小智 5

我刚刚在这上花了很长时间.最终找到了解决方案并且它非常简单.


var enumerableData = myData.Tables[0].AsEnumerable();
var groupedData = enumerableData.GroupBy(x => x["GroupingColumn"]);

myParentRepeater.DataSource = groupedData;
myParentRepeater.DataBind();
Run Code Online (Sandbox Code Playgroud)
<asp:Repeater ID="myParentRepeater" runat="server">
  <ItemTemplate>
    <h3><%#Eval("Key") %></h3>
    <asp:Repeater ID="myChildRepeater" runat="server" DataSource='<%# Container.DataItem %>'>
      <ItemTemplate>
        <%#((DataRow)Container.DataItem)["ChildDataColumn1"] %>
        <%#((DataRow)Container.DataItem)["ChildDataColumn2"] %>
      </ItemTemplate>
      <SeparatorTemplate>
        <br />
      </SeparatorTemplate>
    </asp:Repeater>
  </ItemTemplate>
</asp:Repeater>
Run Code Online (Sandbox Code Playgroud)

Eval("Key")返回分组值.检索子信息时,Container.DataItem属于IGrouping类型,但您只需将其强制转换为正确的类型.

希望这有助于其他人.