【问题标题】:asp.net repeater merge columns dynamicallyasp.net 转发器动态合并列
【发布时间】:2015-05-02 07:00:47
【问题描述】:

我的 ASP.net 页面中有一个中继器。我想合并具有相同文本的列。这应该在我绑定数据表时动态发生。我为此搜索了很多。但是,没有成功。我怀疑是否可以使用中继器。我还要提一下,每一行还有图片按钮和复选框。

这是我的转发器来源:-

<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>

这就是我填充中继器的方式:-

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;
}

【问题讨论】:

  • 感谢您提供简化代码。但我不明白。您能否准确地阐明“合并具有相同文本的列”的含义。您希望最终输出是什么样的?
  • 感谢 Rajeev Goel 的回复。我没有足够的声誉来添加图像。所以,我会试着解释一下。最终输出应该是一个表格,它的第一列的 3 行(橙色)合并了。然后,接下来的 2 行(苹果)合并。但是,这应该动态完成,即如果 row1-cell1 == row2-cell1,则合并它们。可能在 _ItemDataBound 事件中。提前致谢。
  • 但是如果合并行,您将在日期和价格列中显示什么?例如,对于“橙色”,价格可以是 50、51 或 55。那么您要显示哪个价格?
  • 不,它是这样的:- 2015 年 1 月 1 日 Orange 的价格 = 50,2015 年 2 月 1 日 = 51,......
  • 好的,所以您仍然希望在表格中显示三行“Orange”,但在第一列中,文本“Orange”只会出现在第一行,并且会有第 2 行和第 3 行的第一列中没有文本。对吗?

标签: asp.net merge repeater


【解决方案1】:

好的,我让它看起来像这样。我想这就是你想要的:

但我必须对您的代码进行重大更改才能使其正常工作。首先,DataTable 和 DataRow 是相当过时的类......它们不支持 Linq 等。所以我转而只使用普通对象。其次,您将需要在代码隐藏中进行合并。它仍然是“动态的”,因为您不必更改从服务器返回的原始数据。但是您将在绑定到Repeater 控件之前“处理”数据。这是我最终得到的结果:

.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;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 2011-05-04
    • 1970-01-01
    相关资源
    最近更新 更多