基于行级别排序asp.net gridview控件c# [英] Sorting asp.net gridview control based on row level c#

查看:80
本文介绍了基于行级别排序asp.net gridview控件c#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题与



gridview控件允许我按列(从上到下)然而,是否有办法对行进行排序,例如:在行级从左到右,如果您查看(当前格式)屏幕截图并查看第3行,您将看到以下结果:(2a,2c,2x2a ,2c)现在理想情况下,我想将它们组合在一起(3x2a,2x2c),但不确定这是否是正确的方法,因为它会涉及整列移动,我可以想象,如果我们排序第一行正确地转到第二行,我们可能会再次弄乱第一行的结果,不确定这是否会工作或ev可能。



我想让我的gridview控件显示如下数据:

所需格式


  1. 或者可以在asp.net gridview控件中实现?

  2. 我将如何才能实现理想的解决方案?

如果您需要任何附加信息,请询问,我会尽量扩展我的问题。


更新信息: ConnersFan's 建议后,我得到以下结果,



运行完页面后,我得到了这个截图,在每个截图之后,我会解释发生了什么:




^^^ 默认页面加载:这会合并/组合行单元格中的相等值。




^^^ 点击第一行排序链接后,第一行看起来正确,列标题和值都移动到正确的位置。



^ ^^ 点击第二排排序链接后,它会正确排序第二行并且没有弄乱第一行



< a href =https://i.stack.imgur.com/CRo8i .pngrel =nofollow noreferrer>
^^ ^ 点击第三排'排序'链接后,它会混淆第一行和第二行,但设法合并并将第三行分组确定。




^^^ 点击第四行排序链接后,会扰乱第一,第二和第三行,但设法合并和第四行确定好。




^^^ 点击第五行排序链接后,(它们应该没有区别,因为它们都是相同的值,它会扰乱第一,二,三和f第四排,但设法合并和第五排仍然没问题。




^^^ 点击第六排排序链接(这应该没有什么不同,因为它们都是不同的值,它会让剩下的东西混乱。



<因此,我希望看到的是,我们不需要使用按钮对这些进行排序,但只是在页面加载时,所有行都被正确地合并和分组,而不会搞乱上一行,如果正确完成,我们应该结束,所需的格式截图,所以列的顺序是由行单元格中的值决定的,如果它们相等。

非常感谢你们,你已经帮了我很大的忙。

解决方案

如果我正确理解你的问题,你想转置通常的排序com所以它根据一行中的顺序重新排列GridView列,而不是根据列中的顺序重新排列行。



您可以将LinkBut​​ton插入第一列触发特定行的排序(我使用TemplateField而不是ButtonField来设置带有绑定表达式的文本):

 < asp:GridView ID =GridView1runat =serverAutoGenerateColumns =true
OnRowCommand =GridView1_RowCommandOnPreRender =GridView1_PreRender>
<列>
< asp:TemplateField>
< ItemTemplate>
< asp:LinkBut​​ton runat =serverText ='<%#Row+((Container as GridViewRow).RowIndex + 1)%>'CommandName =SortRowCommandArgument ='< %#(Container as GridViewRow).RowIndex%>'/>
< / ItemTemplate>
< / asp:TemplateField>
< /列>
< / asp:GridView>

在代码隐藏中,您可以定义网格左侧的固定列数,以及$ sortRowIndex 变量,它在<

  private const int fixedColumnCount = 1; //行号列
private int sortRowIndex = -1;

protected void GridView1_RowCommand(object sender,GridViewCommandEventArgs e)
{
if(e.CommandName ==SortRow)
{
sortRowIndex = Convert .ToInt32(e.CommandArgument);
//在这里设置数据源并将数据绑定到GridView
GridView1.DataSource = ...
GridView1.DataBind();






排序本身可以在数据源中执行,正如您在上一篇文章中fnostro所建议的那样。因为我不知道数据是什么样的,所以这里有一种方法可以在网格中完成它。



这项工作可以在 PreRender 或者在GridView的 DataBound 事件中。用相同内容对单元进行分组的代码,见你的其他帖子,也应该在这个事件处理器中移动,并放在排序操作之后。

  protected void GridView1_PreRender(object sender,EventArgs e)
{
List< int> sortedColIndexes = null;

if(sortRowIndex> = 0)
{
//收集已排序行的单元格数据...
List< KeyValuePair< string,int> > cellsToSort = new List< KeyValuePair< string,int>>();
sortedColIndexes = new List< int>();

GridViewRow sortedRow = GridView1.Rows [sortRowIndex];
for(int i = fixedColumnCount; i< sortedRow.Cells.Count; i ++)
{
TableCell cell = sortedRow.Cells [i];
cellsToSort.Add(new KeyValuePair< string,int>(cell.Text,i));
}

// ...并根据单元格内容对单元格索引进行排序
sortedColIndexes = cellsToSort.OrderBy(x => x.Key).Select(x => x.Value).ToList();
}

RearrangeRowCells(GridView1.HeaderRow,sortedColIndexes);

foreach(GridView1.Rows中的GridViewRow行)
{
RearrangeRowCells(row,sortedColIndexes);

//下面的代码取自另一个帖子
//它将具有相同内容的单元格合并为
(int i = 0; i< row.Cells .Count - 1; i ++)
{
TableCell cell = row.Cells [i];

if(cell.Visible)
{
int colSpanValue = 1;

for(int j = i + 1; j {
TableCell otherCell = row.Cells [j];

if(otherCell.Text == cell.Text)
{
colSpanValue ++;
otherCell.Visible = false;
}
else
{
break;
}
}

if(colSpanValue> 1)
{
cell.ColumnSpan = colSpanValue;
cell.BackColor = System.Drawing.Color.Beige;
cell.Horizo​​ntalAlign = Horizo​​ntalAlign.Center;






//在给定行上执行单元排列的效用函数
private void RearrangeRowCells(GridViewRow row,List< int> sortedColIndexes)
{
if(sortedColIndexes!= null)
{
List< TableCell> sortedCells = new List< TableCell>();

foreach(在sortedColIndexes中的cellIndex)
{
sortedCells.Add(row.Cells [cellIndex]);


for(int i = fixedColumnCount; i< sortedCells.Count - 1; i ++)
{
row.Cells.Remove(sortedCells [i] );
row.Cells.AddAt(i + fixedColumnCount,sortedCells [i]);
}
}
}


My issue is related to an earlier question on stackoverflow. In my previous question I needed to merge columns with the same values in a c# asp.net Gridview Control. This problem was resolved by the excellent help and support from other stackoverflowers, however I'm also required to sort the order on row level e.g:

Current format:

The gridview control allows me to sort values by columns (top to bottom) however would there be a way to sort the rows, e.g: left to right on row level, if you take a look at the (Current format) screenshot and check row 3, you will see the following result: ( 2a, 2c, 2x2a, 2c ) Now ideally I would like to group these together as in ( 3x2a, 2x2c ), but not sure if this would be the correct approach as it would involve shifting the whole column, and I could imagine that if we sort the first row correctly and go to the second row, we might mess up the first row result again, not sure if this would work or even possible.

I would like to have my gridview control displaying the data as following:

Required format:

  1. Would this be the approach or achievable in a asp.net gridview control?
  2. How would I be able to achieve the ideal solution otherwise?

If you need any additional information, please ask and i will try to expand my question.

UPDATED INFORMATION:

After ConnersFan's suggestion, I got the following result, the idea is sort of there, but not quite yet.

After running the page i get this screenshots, after each screenshot i will explain what happens:

^^^ DEFAULT PAGE LOAD: This merges/groups the equal values in the row cell together.

^^^ After clicking on the first row 'sort' link, the first row looks correct, the column header and values are all moving to the correct place.

^^^ After clicking on the second row 'sort' link, it sorts the second row correctly and has not messed up the first row

^^^ After clicking on the third row 'sort' link, it messes up the first and second row, but managed to merge and group the third row ok.

^^^ After clicking on the fourth row 'sort' link, it messes up the first, second and third row, but managed to merge and group the fourth row ok.

^^^ After clicking on the fifth row 'sort' link, (which should not make a difference as they are all the same equal value, it messes up the first, second, third and fourth row, but managed to merge and group the fifth row still ok.

^^^ After clicking on the sixth row 'sort' link, (which should not make a difference as they are all different values, it messes the rest up.

So, what i would love to see is that, we dont need to sort these with a button but just on page load all rows are correctly merged and grouped, without messing up the previous row and we should end up, if done correctly, with the required format screenshot, so the order of the columns is determined by the values in the row cells, if they are equal.

Thank you guys ever so much, you have helped me out greatly already.

解决方案

If I understand your question correctly, you want to transpose the usual sort command, so that it rearranges the GridView columns according to the order in a row rather than rearranging the rows according to the order in a column.

You can insert a LinkButton in the first column to trigger the sort on a specific row (I used a TemplateField instead of a ButtonField in order to set the text with a binding expression):

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="true" 
    OnRowCommand="GridView1_RowCommand" OnPreRender="GridView1_PreRender">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:LinkButton runat="server" Text='<%# "Row " + ((Container as GridViewRow).RowIndex + 1) %>' CommandName="SortRow" CommandArgument='<%# (Container as GridViewRow).RowIndex %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

In code-behind, you can define the number of fixed columns at the left of the grid, and a sortRowIndex variable which is set in the RowCommand event handler:

private const int fixedColumnCount = 1; // Row number column
private int sortRowIndex = -1;

protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName == "SortRow")
    {
        sortRowIndex = Convert.ToInt32(e.CommandArgument);
        // Here set the data source and bind the data to the GridView
        GridView1.DataSource = ...
        GridView1.DataBind();
    }
}

The sort itself could be performed in the data source, as suggested by fnostro in your previous post. Since I don't know what the data looks like, here is one way to do it in the grid.

The work can be done in the PreRender or in the DataBound event of the GridView. The code to group the cells with the same content, given in your other post, should be moved in this event handler as well, and placed after the sort operations.

protected void GridView1_PreRender(object sender, EventArgs e)
{
    List<int> sortedColIndexes = null;

    if (sortRowIndex >= 0)
    {
        // Gather the cell data on the sorted row...
        List<KeyValuePair<string, int>> cellsToSort = new List<KeyValuePair<string, int>>();
        sortedColIndexes = new List<int>();

        GridViewRow sortedRow = GridView1.Rows[sortRowIndex];
        for (int i = fixedColumnCount; i < sortedRow.Cells.Count; i++)
        {
            TableCell cell = sortedRow.Cells[i];
            cellsToSort.Add(new KeyValuePair<string, int>(cell.Text, i));
        }

        // ... and sort the cell indexes according to the cell content
        sortedColIndexes = cellsToSort.OrderBy(x => x.Key).Select(x => x.Value).ToList();
    }

    RearrangeRowCells(GridView1.HeaderRow, sortedColIndexes);

    foreach (GridViewRow row in GridView1.Rows)
    {
        RearrangeRowCells(row, sortedColIndexes);

        // The code below is taken from the other post
        // It merges the cells with the same content
        for (int i = 0; i < row.Cells.Count - 1; i++)
        {
            TableCell cell = row.Cells[i];

            if (cell.Visible)
            {
                int colSpanValue = 1;

                for (int j = i + 1; j < row.Cells.Count; j++)
                {
                    TableCell otherCell = row.Cells[j];

                    if (otherCell.Text == cell.Text)
                    {
                        colSpanValue++;
                        otherCell.Visible = false;
                    }
                    else
                    {
                        break;
                    }
                }

                if (colSpanValue > 1)
                {
                    cell.ColumnSpan = colSpanValue;
                    cell.BackColor = System.Drawing.Color.Beige;
                    cell.HorizontalAlign = HorizontalAlign.Center;
                }
            }
        }
    }
}

// Utility function which performs the cell permutations on a given row
private void RearrangeRowCells(GridViewRow row, List<int> sortedColIndexes)
{
    if (sortedColIndexes != null)
    {
        List<TableCell> sortedCells = new List<TableCell>();

        foreach (int cellIndex in sortedColIndexes)
        {
            sortedCells.Add(row.Cells[cellIndex]);
        }

        for (int i = fixedColumnCount; i < sortedCells.Count - 1; i++)
        {
            row.Cells.Remove(sortedCells[i]);
            row.Cells.AddAt(i + fixedColumnCount, sortedCells[i]);
        }
    }
}

这篇关于基于行级别排序asp.net gridview控件c#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆