简体   繁体   English

如何使用父项的项目ID在子级ListView中呈现相关项

[英]How to render related items in a child ListView using the item ID from the parent

I have a nested list view and the goal is to pull the ID from outer list view and pass it into the method below as the CurrentCategoryId This will allow my second list view to populate correctly. 我有一个嵌套列表视图,目标是从外部列表视图中提取ID并将其作为CurrentCategoryId传递到下面的方法中,这将允许我的第二个列表视图正确填充。 From what i read this should be done with a eventhandler OnItemDataBound but i am having trouble understanding how it that works? 从我阅读的内容来看,应该使用事件处理程序OnItemDataBound完成此操作,但是我在理解其工作原理时遇到了麻烦。

Please let me know if you have any questions 请让我知道,如果你有任何问题

<asp:ListView ID="ListView1"
    ItemType="E_Store_Template.Models.Category"
    runat="server"
    SelectMethod="GetCategories"
    OnItemDataBound="brandList_ItemDataBound">
    <ItemTemplate>
        <ul>
            <li style="list-style-type: none; text-align: left;">
                <b style="font-size: large; font-style: normal">
                    <a href="<%#: GetRouteUrl("ProductsByCategoryRoute", new {categoryName = Item.CategoryName}) %>">
                        <%#: Item.CategoryName %>
                    </a>
                    <asp:ListView ID="brandList" runat="server" ItemType="E_Store_Template.Models.Brand">
                        <ItemTemplate>
                            <ul style="list-style-type: none; text-align: left;">
                                <li>
                                    <a href="<%#: GetRouteUrl("ProductsByCatBrandRoute", new {brandName = Item.BrandName}) %>">
                                        <%#: Item.BrandName %>
                                    </a>
                                </li>
                            </ul>
                        </ItemTemplate>
                    </asp:ListView>
                </b>
            </li>
        </ul>
    </ItemTemplate>
</asp:ListView>

I think the event handler needs to look like this 我认为事件处理程序需要看起来像这样

protected List<Brand> brandList_ItemDataBound(object sender, ListViewItemEventArgs e)
{
    ListViewDataItem dataItem = (ListViewDataItem)e.Item;

    if (e.Item.ItemType == ListViewItemType.DataItem)
    {
        Category mydata = (Category)dataItem.DataItem;
        int CurrentCategoryId = mydata.CategoryID;
        var query = _db.Products.Where(p => p.Category.CategoryID == CurrentCategoryId).Select(p => p.Brand).Distinct();
        return query.ToList<Brand>();
    }
    else
    {
        return null;
    }
}

but gives me the error: 但给我错误:

'System.Collections.Generic.List<E_Store_Template.Models.Brand> E_Store_Template.SiteMaster.brandList_ItemDataBound(object, System.Web.UI.WebControls.ListViewItemEventArgs)' has the wrong return type

ItemDataBound isn't designed to return data, it is designed to handle an event. ItemDataBound并非旨在返回数据,而是旨在处理事件。 In this case the event is rendering a category and anything that needs to happen as a child event. 在这种情况下,事件将呈现一个类别以及需要作为子事件发生的所有事件。 The proper course of action is to get the child ListView from the parent item and bind your data to it. 正确的做法是从父项获取子ListView并将其绑定到数据。 Markup: 标记:

<asp:ListView ID="categoryList" runat="server"
    OnItemDataBound="brandList_ItemDataBound" ItemType="E_Store_Template.Models.Category" SelectMethod="GetCategories">
        <LayoutTemplate>
            <ul style="list-style-type: none;">
                <asp:PlaceHolder runat="server" ID="itemPlaceholder" />
            </ul>
        </LayoutTemplate>
        <ItemTemplate>
            <li style="text-align: left;">
                <b style="font-size: large; font-style: normal">
                    <a href="<%#: GetRouteUrl("ProductsByCategoryRoute", new {categoryName = Item.CategoryName}) %>">
                        <%#: Item.CategoryName %>
                    </a>
                </b>
                <asp:ListView ID="brandList" runat="server">
                    <LayoutTemplate>
                        <ul style="list-style-type: none; text-align: left;">
                            <asp:PlaceHolder runat="server" ID="itemPlaceholder" />
                        </ul>
                    </LayoutTemplate>
                    <ItemTemplate>
                        <li>
                            <a href="<%#: GetRouteUrl("ProductsByCatBrandRoute", new {brandName = Item.BrandName}) %>">
                                <%#: Item.BrandName %>
                            </a>
                        </li>
                    </ItemTemplate>
                </asp:ListView>
            </li>
        </ItemTemplate>
    </asp:ListView>

Code behind: 后面的代码:

protected void brandList_ItemDataBound(object sender, ListViewItemEventArgs e)
{
    ListViewDataItem dataItem = (ListViewDataItem)e.Item;

    if (e.Item.ItemType == ListViewItemType.DataItem)
    {
        Category mydata = (Category)dataItem.DataItem;

        int CurrentCategoryId = mydata.CategoryID;
        var query = _db.Products.Where(p => p.Category.CategoryID == CurrentCategoryId).Select(p => p.Brand).Distinct();

        ListView brandList = (ListView)e.Item.FindControl("brandList");
        brandList.DataSource = query.ToList<Brand>();
        brandList.DataBind();
    }
}

I added LayoutTemplates with PlaceHolders so your ListView doesn't repeat your tags for each record. 我添加了带有PlaceHolders的LayoutTemplates,因此您的ListView不会为每个记录重复您的标签。 I also moved your closing tag because you shouldn't have a block element (unordered list) as a child of a bold tag set. 我还移动了结束标签,因为您不应该将块元素(无序列表)作为粗体标签集的子元素。

I would consider getting all the Categories and Brands in 1 (or 2) SQL queries then filtering the Brands data list by the appropriate CategoryID. 我会考虑在1(或2)个SQL查询中获取所有类别和品牌,然后按适当的CategoryID过滤品牌数据列表。 You would store the Brands data list as a page level variable, but don't load it into Session or ViewState, you only need it during the page rendering. 您可以将Brands数据列表存储为页面级变量,但不要将其加载到Session或ViewState中,只需要在页面呈现期间使用它即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM