Показать категорию один раз в репитере - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть повторитель, который хочет отображать категории и продукты. Категория должна появиться один раз, и продукты будут отображать количество продуктов, которые у меня есть. Ниже моя разметка

<asp:Repeater ID="rpt1" runat="server" OnItemDataBound="rpt1_ItemDataBound">
    <ItemTemplate>
        <asp:Label ID="lblCategory" runat="server"></asp:Label>
        <asp:Label ID="lblProductName" runat="server"></asp:Label>
    </ItemTemplate>
</asp:Repeater>

Я связываю продукты при загрузке страницы

if (!Page.IsPostBack)
{
    LoadData();
}

Мой код позади

protected void rpt1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
    {
        Product p = (Product)e.Item.DataItem;

        Label lblCategory = e.Item.FindControl("lblCategory") as Label;
        Label lblProductName = e.Item.FindControl("lblProductName") as Label;

        lblProductName.Text = p.ProductName;
        lblCategory.Text = p.Category.CategoryName;
    }
}

Все работает, но текст моей категории повторяется более один раз (показано количество продуктов, которые у меня есть). Как я могу отобразить категорию только один раз?

Редактировать

Cat 20 is Stationery
Cat 30 is Computer Items
Cat 40 is Toiletry

**Id CatId ProductName**
1   20     Pencil
1   20     Pen
1   30     Compact Disc
1   30     USB
1   30     Hard drive
1   40     Toothpaste
1   40     Toothbrush

Я получаю свои данные в

Iqueryable<Product> LoadData = myContext.GetProducts();

Ответы [ 2 ]

2 голосов
/ 01 апреля 2020

Я думаю, что использование вложенного повторителя было бы лучше в этом случае. Я имею в виду первый ретранслятор для Categories и вложенный ретранслятор для Products этой категории. См .: Вложенный повторитель .

<asp:Repeater runat="server" id="Categories">
  <ItemTemplate>
    Category: <%# Eval("CategoryName") %>
    Products:
    <asp:Repeater runat="server" DataSource='<%# Eval("Products") %>'>
      <ItemTemplate><%# Eval("ProductName") %></ItemTemplate>
    </asp:Repeater>
  </ItemTemplate>
</asp:Repeater>

Но для этого вам нужно немного поработать с моделью данных, ваша модель должна выглядеть следующим образом:

public class Category 
{
    public string CategoryName {get; set;}
    public IEnumerable<Product> Products {get; set;}
}

public class Product 
{
    public string ProductName {get; set;}
}

Или грязно-быстрое решение заключается в сравнении имени категории к предыдущему ряду для каждого элемента репитера. Если имя категории изменилось, отобразите новое имя категории, в противном случае оставьте пустым:

protected void rpt1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
    {
        Product p = (Product)e.Item.DataItem;

        Label lblCategory = e.Item.FindControl("lblCategory") as Label;
        Label lblProductName = e.Item.FindControl("lblProductName") as Label;

        lblProductName.Text = p.ProductName;

        if(e.Item.ItemIndex > 0)
        {
            RepeaterItem previousRepeaterItem = rpt1.Items[e.Item.ItemIndex - 1];
            var previousCategoryName = (previousRepeaterItem.FindControl("lblCategory") as Label).Text;
            if(previousCategoryName != p.Category.CategoryName)
            {
                lblCategory.Text = p.Category.CategoryName; 
            }
        }
    }
}
0 голосов
/ 01 апреля 2020

Я не уверен в сложности данных продукта, которые вы sh отобразите. Тем не менее, я хотел бы предложить вам использовать вложенный Repeaters, у одного повторителя будет название категории, а у второго - продукты. На Page_Load вы должны выбрать все отдельные категории и связать первый ретранслятор. На ItemDataBound первого ретранслятора вы должны выбрать продукты, относящиеся к категории, и связать вложенный ретранслятор.

например:

<asp:Repeater ID="rpt1" runat="server" OnItemDataBound="rpt1_ItemDataBound">
    <ItemTemplate>
        <asp:Label ID="lblCategory" runat="server" Text='<%# Eval("Category") %>'></asp:Label>
        <asp:Repeater ID="rpt2" runat="server">
            <ItemTemplate>
                <asp:Label ID="lblProductName" runat="server" Text='<%# Eval("ProductName")%>'></asp:Label>
            </ItemTemplate>
        </asp:Repeater>
    </ItemTemplate>
</asp:Repeater>

Загрузка страницы:

protected void Page_Load(object s, EventArgs e)
{
    // Fetch All the Categories, Distinct Elements
    DataTable dt = new DataTable();
    dt.Columns.Add("Category");
    dt.Rows.Add("Sanatizers");
    dt.Rows.Add("Soaps");
    rpt1.DataSource = dt;
    rpt1.DataBind();
}

Данные элемента Ограничение:

protected void rpt1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
    {
        Label lblCategory = (Label)e.Item.FindControl("lblCategory");

        Repeater rpt2 = (Repeater)e.Item.FindControl("rpt2");
        if (lblCategory != null)
        {
            // Fetch products by category
            var dt = new DataTable();
            dt.Columns.Add("ProductName");
            dt.Rows.Add("Dettol");
            dt.Rows.Add("Safeguard");
            dt.Rows.Add("Fair and Lovely");
            rpt2.DataSource = dt;
            rpt2.DataBind();
        }
    }
}

PS: Код не проверен, возможно, потребуется некоторая любовь.

...