asp.net repeater merge columns dynamically

非 Y 不嫁゛ 提交于 2019-12-24 07:19:19

问题


I have a repeater in my ASP.net page. I want to merge the columns which have same text. This should happen dynamically when I bind a datatable. I have searched a lot for this. But, without success. I doubt whether it is possible with a repeater. I would also like to mention that there are also image buttons and check boxes in each row.

This is my repeater source:-

<asp:Repeater ID="rpt1" runat="server" onitemcommand="rpt1_ItemCommand">
        <HeaderTemplate>
            <table border="1" cellpadding="10" width="50%">
            <tr>
                <th>Item Name</th>
                <th>As On</th>
                <th>Price</th>
                <th></th>
                <th></th>
            </tr>
        </HeaderTemplate>
        <ItemTemplate>

            <tr>
                <td>
                    <asp:Label ID="lblRelayName" runat="server" Text='<%# Eval("ItemName") %>'></asp:Label>
                </td>
                <td>
                    <asp:Label ID="lblTimeFrom" runat="server" Text='<%# Eval("Date") %>'></asp:Label>
                </td>
                <td>
                    <asp:Label ID="lblPrice" runat="server" Text='<%# Eval("Price") %>'></asp:Label>
                </td>
                <td>
                    <asp:ImageButton ID="imgBtnStatus" runat="server" 
                        ImageUrl="~/img/btnGet.jpg" 
                        CommandName="Change"  style="width: 36px; border-width: 0px; margin-top: -4px; vertical-align: middle;" />
                </td>
                <td>
                    <asp:CheckBox ID="chkStatus" runat="server" Checked="true" />
                </td>
            </tr>

        </ItemTemplate>
        <FooterTemplate>
            </table>
        </FooterTemplate>

        </asp:Repeater>

This is how I fill the repeater:-

protected void Page_Load(object sender, EventArgs e)
{
    rpt1.DataSource = GetData();
    rpt1.DataBind();
}

private DataTable GetData()
{
    DataTable dt = new DataTable();
    dt.Columns.Add("ItemName");
    dt.Columns.Add("Date");
    dt.Columns.Add("Price");

    DataRow dr = dt.NewRow();
    dr["ItemName"] = "Orange";
    dr["Date"] = "01/01/2015";
    dr["Price"] = "50";
    dt.Rows.Add(dr);

    dr = dt.NewRow();
    dr["ItemName"] = "Orange";
    dr["Date"] = "02/01/2015";
    dr["Price"] = "51";
    dt.Rows.Add(dr);

    dr = dt.NewRow();
    dr["ItemName"] = "Orange";
    dr["Date"] = "03/01/2015";
    dr["Price"] = "55";
    dt.Rows.Add(dr);

    dr = dt.NewRow();
    dr["ItemName"] = "Apple";
    dr["Date"] = "01/01/2015";
    dr["Price"] = "95";
    dt.Rows.Add(dr);

    dr = dt.NewRow();
    dr["ItemName"] = "Apple";
    dr["Date"] = "03/01/2015";
    dr["Price"] = "98";
    dt.Rows.Add(dr);

    dr = dt.NewRow();
    dr["ItemName"] = "Banana";
    dr["Date"] = "01/01/2015";
    dr["Price"] = "48";
    dt.Rows.Add(dr);

    return dt;
}

回答1:


Okay, I was able to get it to look like this. I think this is what you wanted:

But I had to make significant changes to your code to make this work. Firstly, DataTable and DataRow are pretty outdated classes ... they don't support Linq, etc. So I switched to just using plain objects. Secondly, you are going to need to do the merging in your code-behind. It's still "dynamic" in the sense that you won't have to change the raw data that is coming back from the server. But you will have "process" the data before binding to the Repeater control. Here's what I ended up with:

.ASPX:

<asp:Repeater ID="rpt1" runat="server">
    <HeaderTemplate>
        <table border="1" cellpadding="10" width="50%">
            <tr>
                <th>Item Name</th>
                <th>As On</th>
                <th>Price</th>
                <th></th>
                <th></th>
            </tr>
    </HeaderTemplate>
    <ItemTemplate>
        <tr>
            <td style='vertical-align: top; display: <%# ((bool) Eval("IsFirstRowWithThisItemName")) ? "" : "none" %>;' 
                rowspan="<%# Eval("CountOfProductsWithThisItemName") %>">
                <asp:Label ID="lblRelayName" runat="server" Text='<%# Eval("ItemName") %>'></asp:Label>
            </td>
            <td>
                <asp:Label ID="lblTimeFrom" runat="server" Text='<%# Eval("ShortDate") %>'></asp:Label>
            </td>
            <td>
                <asp:Label ID="lblPrice" runat="server" Text='<%# Eval("PriceDisplay") %>'></asp:Label>
            </td>
            <td>
                <asp:ImageButton ID="imgBtnStatus" runat="server"
                    ImageUrl="~/img/btnGet.jpg"
                    CommandName="Change" Style="width: 36px; border-width: 0px; margin-top: -4px; vertical-align: middle;" />
            </td>
            <td>
                <asp:CheckBox ID="chkStatus" runat="server" Checked="true" />
            </td>
        </tr>
    </ItemTemplate>
    <FooterTemplate>
        </table>
    </FooterTemplate>
</asp:Repeater>

.ASPX.CS

public partial class About : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        rpt1.DataSource = this.GetMergedData(this.GetData());
        rpt1.DataBind();

    }

    private List<Product> GetMergedData(List<Product> allProducts)
    {
        List<Product> mergedProducts = new List<Product>();

        var groupingsByName =
            allProducts
            .GroupBy(product => product.ItemName);

        foreach (var groupingByName in groupingsByName)
        {
            Product firstProduct = groupingByName.First();
            firstProduct.CountOfProductsWithThisItemName = groupingByName.Count();
            firstProduct.IsFirstRowWithThisItemName = true;
            mergedProducts.Add(firstProduct);

            mergedProducts.AddRange(groupingByName.Skip(1));
        }

        return mergedProducts;
    }

    private List<Product> GetData()
    {
        return new List<Product>()
        {
            new Product("Orange", DateTime.Parse("01/01/2015"), 50),
            new Product("Orange", DateTime.Parse("02/01/2015"), 51),
            new Product("Orange", DateTime.Parse("03/01/2015"), 55),
            new Product("Apple", DateTime.Parse("01/01/2015"), 95),
            new Product("Apple", DateTime.Parse("03/01/2015"), 98),
            new Product("Banana", DateTime.Parse("01/01/2015"), 48),
        };
    }
}

public class Product
{
    public string ItemName { get; set; }
    public DateTime Date { get; set; }
    public decimal Price { get; set; }
    public string ShortDate { get { return this.Date.ToShortDateString();  } }
    public string PriceDisplay { get { return this.Price.ToString("C");  } }

    public int CountOfProductsWithThisItemName { get; set; }
    public bool IsFirstRowWithThisItemName { get; set; }

    public Product(string itemName, DateTime date, decimal price)
    {
        this.ItemName = itemName;
        this.Date = date;
        this.Price = price;
    }
}


来源:https://stackoverflow.com/questions/29999444/asp-net-repeater-merge-columns-dynamically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!