【问题标题】:How to merge multiple columns values into one column? Asp.net Gridview C#如何将多列值合并为一列? Asp.net Gridview C#
【发布时间】:2016-10-11 15:49:24
【问题描述】:

首先我不知道这是否可能,正确的方法甚至会起作用,但我希望你们能帮助我,我会尽力解释:

我在 ASPX 页面上有一个 GridView 控件:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="True" OnRowDataBound="GridView1_RowDataBound" GridLines="None" CssClass="table table-striped" />

我在代码隐藏中创建了一个 DataTable,其中包含以下数据并将其绑定到 Gridview 控件:

-----------------------------------------
|       | Name1 | Name2 | Name3 | Name4 |
-----------------------------------------
| Row1  | 1     | 1     | 1     | 1b    |
| Row2  | 1a    | 2b    | 2b    | 4b    |
| Row3  | 2a    | 2c    | 2a    | 2a    |
| Row4  | 1d    | 1d    | 1d    | 4d    |
| Row5  | 1e    | 1e    | 1e    | 1e    |
| Row6  | 1f    | 2f    | 3f    | 4f    |
-----------------------------------------

现在我想合并匹配的列值并添加适当的 colspan。我在 GridView 控件中添加了一个 OnRowDataBound,如下所示:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        if (e.Row.RowIndex >= 0)
        {
            int colSpanValue = 2;
            for (int i = 0; i < e.Row.Cells.Count; i++)
            {
                if (i+1 < e.Row.Cells.Count) 
                {
                    if (e.Row.Cells[i].Text == e.Row.Cells[i + 1].Text)
                    {
                        e.Row.Cells[i].BackColor = Color.Beige;
                        e.Row.Cells[i].ColumnSpan = colSpanValue;
                        e.Row.Cells[i].HorizontalAlign = HorizontalAlign.Center;
                        e.Row.Cells[i + 1].Visible = false;
                        colSpanValue++;
                    }
                }
            }
        }
    }
}

所以上面的数据是这样的,像这样的。

-----------------------------------------
|       | Name1 | Name2 | Name3 | Name4 |
-----------------------------------------
| Row1  |       1       | 1b            | <!-- problem
| Row2  | 1a    |      2b       | 4b    |
| Row3  | 2a    | 2c    |      2a       | <!-- problem
| Row4  |           1d          | 4d    |
| Row5  |              1e               |
| Row6  | 1f    | 2f    | 3f    | 4f    |
-----------------------------------------

目前我设法得到了这个,看截图

然而,这并不是我真正希望看到的,而是期望的,因为 OnRowDataBound 代码块可能没有正确完成。

所以我的问题是:

  • 如何合并一行中所有相等的列并向它们添加 colspan?
  • 现在对于棘手的问题,我能否对列进行排序,以便正确显示匹配的列单元格? (不确定)

所以理想的结果应该是这样的:

-----------------------------------------
|       | Name1 | Name2 | Name3 | Name4 |
-----------------------------------------
| Row1  |           1           | 1b    | <!-- problem
| Row2  | 1a    |      2b       | 4b    |
| Row3  | 2a    | 2c    |      2a       | <!-- problem
| Row4  |           1d          | 4d    |
| Row5  |              1e               |
| Row6  | 1f    | 2f    | 3f    | 4f    |
-----------------------------------------

更新信息

根据ConnorsFanfnostro提供的答案更新代码后,两个答案都正确且有效,感谢您的帮助。 我选择 ConnorsFan 的方法,因为我还在学习。

现在的 colspan 是正确的,请看下面的截图:

我会尝试fnostro 的 建议通过DataTable 管理排序部分并将数据重新绑定到GridView1 并随时通知您。再次感谢您的回答。

【问题讨论】:

    标签: c# asp.net gridview


    【解决方案1】:

    你可以试试这个:

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            for (int i = 0; i < e.Row.Cells.Count - 1; i++)
            {
                TableCell cell = e.Row.Cells[i];
    
                if (cell.Visible)
                {
                    int colSpanValue = 1;
    
                    for (int j = i + 1; j < e.Row.Cells.Count; j++)
                    {
                        TableCell otherCell = e.Row.Cells[j];
    
                        if (otherCell.Text == cell.Text)
                        {
                            colSpanValue++;
                            otherCell.Visible = false;
                        }
                        else
                        {
                            break;
                        }
                    }
    
                    if (colSpanValue > 1)
                    {
                        cell.ColumnSpan = colSpanValue;
                        cell.BackColor = Color.Beige;
                        cell.HorizontalAlign = HorizontalAlign.Center;
                    }
                }
            }
        }
    }
    

    【讨论】:

    • 非常感谢,效果很好,我添加了更新信息,包括您回答结果的屏幕截图。
    【解决方案2】:

    关于排序。最好在 DataTable 中管理排序并简单地重新绑定到 GridView

    以下是我如何修改 RowDataBound 事件以合并类似数据:

        protected void GridView1_RowDataBound( object sender, GridViewRowEventArgs e ) 
        {
          if ( e.Row.RowType == DataControlRowType.DataRow ) 
          {
            // loop through cells and track span index (si)
            for ( int i = 0, si = 0; i < e.Row.Cells.Count; si = i) 
            {
              // compare adjacent cells for like data and hide as needed
              while ( ++i < e.Row.Cells.Count && e.Row.Cells[ si ].Text == e.Row.Cells[ i ].Text )
                e.Row.Cells[ i ].Visible = false;
    
              // set span and, conditionally, special formatting
              if ( ( e.Row.Cells[ si ].ColumnSpan = ( i - si ) ) > 1 ) 
              {
                e.Row.Cells[ si ].BackColor = Color.Beige;
                e.Row.Cells[ si ].HorizontalAlign = HorizontalAlign.Center;
              }
            }
          }
        }
    

    【讨论】:

    • 感谢您对列排序的建议,我会看看如何实现这一点。
    • 很高兴为您提供帮助。查看LinqSee this SO question
    • 这允许我按列中的值排序(从上到下)但是有没有办法对行进行排序,例如:如果你看一下,在行级别从左到右我更新的信息并检查第 3 行,您将看到以下结果: ( 2a, 2b, 2x2a ) 现在理想情况下,我想将这些组合在一起,但不确定这是否是正确的方法,因为它涉及移动整个列,但我可以想象,如果我们正确地对第一行进行排序,然后转到第二行,我们可能会再次弄乱第一行的结果,不确定这是否会起作用。
    • 组怎么样?这样你就有(3x2a,2c)?按行排序将是一件苦差事,因为通常数据表是按列排序的。您可以滚动您自己的按行排序的排序过程。或者您可以“透视”数据表并正常排序。我不知道您总体上要完成什么。您是否尝试先按列排序,然后按行分组?还是 Col 排序、分组、行排序、重新分组的某种组合???
    • HI fnostro,正如你所说:这样你有(3x2a,2c)?确实,但是我可能需要为这个问题打开另一个问题,正如您提到的并且我已经发现,按行排序似乎是一件苦差事,并且确实已经注意到按列排序的一切都准备就绪,但是行是另一回事,完全可以理解,这就是为什么我认为带有数据表的 gridview 控件可能不是满足我要求的理想解决方案的原因,其背后的想法是将共享值彼此相邻显示并合并,以便您可以查看共享的列相同的行数据值。谢谢
    猜你喜欢
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    • 2018-11-04
    • 1970-01-01
    相关资源
    最近更新 更多