【问题标题】:Datagridview sorting column based on matching string基于匹配字符串的Datagridview排序列
【发布时间】:2012-07-03 05:00:19
【问题描述】:

我有一个数据网格视图,我希望根据用户输入的字符串部分对行进行排序。将输入的字符串与特定列中的所有字符串进行比较。例如,如果我将“comp”作为搜索词,程序将尝试将搜索词与第一列的字符串进行比较,并以“comp”开头的降序对行进行排序,例如“compare”, “作文”、“计算机”等。其余不匹配的单词要么单独放置,要么按字母顺序排序(以更容易的为准)。

在 LINQ 中,我知道您可以应用以下代码来实现您想要的字符串数组:

var sortedWords = words.Where(x => x.Contains("comp"))
                       .OrderByDescending(x => x);

如何在 Datagridview 中实现与需要对行进行排序的相同操作,而不仅仅是特定列中的项目?

编辑:

以下代码给出了 System.InvalidOperationException。 (SetCurrentCellAddressCore 被调用了两次)

    private void DGVPointCtrl_CellEndEdit(object sender, DataGridViewCellEventArgs e)
    {
        MatchComparer mc = new MatchComparer();
        DGVPointCtrl.Sort(mc); //Error
    }

我可能做错了什么,但我不知道为什么。这是以编程方式添加行以进行测试的代码:

private void BtnRefresh_Click(object sender, EventArgs e)
        {
            try
            {
                DGVPointCtrl.Rows.Clear();
                int mainIndex = CmbMainDevice.SelectedIndex;
                int subIndex = CmbSubDevice.SelectedIndex;
                DDCDAO ddcdao = new DDCDAO(DDCGlobal.ddcEngineIP, ddc.Ip);
                string pointListType;
                object rs;

                //Currently only supports IO DDC Request
                //TO DO: Change DDCDAO to send proper subdevice requests

                if (mainIndex == 0) //IO
                {
                    #region Main Device: IO
                }


                //First row is for searching items
                DGVPointCtrl.Rows.Add(new DataGridViewRow());
                for (int i = 1; i < 5; i++)
                {
                    DGVPointCtrl.Rows.Add(new DataGridViewRow());
                    DGVPointCtrl.Rows[i].ReadOnly = true;
                }
                DGVPointCtrl.Columns[0].SortMode = DataGridViewColumnSortMode.Programmatic;
                DGVPointCtrl.Rows[0].DefaultCellStyle.Font =
                new Font(DGVPointCtrl.DefaultCellStyle.Font, FontStyle.Italic | FontStyle.Bold);

                if (subIndex == 1) //BI
                {
                    PointDGVColumnGenerate("IO_BI");

                }
                else if (subIndex == 2) //BO
                {
                    PointDGVColumnGenerate("IO_BO");
                }
                else if (subIndex == 3) //AI
                {
                    PointDGVColumnGenerate("IO_AI");
                }
                else if (subIndex == 4) //AO
                {
                    PointDGVColumnGenerate("IO_AO");
                }

                DGVPointCtrl.Rows[1].Cells[0].Value = "IO12314";
                DGVPointCtrl.Rows[2].Cells[0].Value = "IO21948";
                DGVPointCtrl.Rows[3].Cells[0].Value = "IO28194";
                DGVPointCtrl.Rows[4].Cells[0].Value = "VP12984";
                DGVPointCtrl.Rows[2].Cells[1].Value = "asdf";

                #endregion
            }
            catch
            {
            }
      }

    private void PointDGVColumnGenerate(string key)
    {
        int colCount = 0;
        DGVColumnTable.Clear();

        for (int i = 0; i < COL_MAX; i++)
        {
            DGVPointCtrl.Columns[i].HeaderText = "   ";
            DGVPointCtrl.Columns[i].Visible = true;
        }

        foreach (string s in UIConstant.DDCPCtrlListColumnText[key])
        {
            DGVPointCtrl.Columns[colCount].HeaderText = s;
            DGVColumnTable.Add(DGVPointCtrl.Columns[colCount]);
            colCount++;
        }
    }

编辑2:

public class MatchComparer : IComparer
{
    private static IComparer defaultComparer = new CaseInsensitiveComparer();
    int IComparer.Compare(object x, object y)
    {
        DataGridViewRow xr = (DataGridViewRow)x;
        DataGridViewRow yr = (DataGridViewRow)y;

        string xs = "";
        string ys = "";
        try
        {
            xs = xr.Cells[0].Value.ToString();
        }
        catch
        {
        }
        try
        {
            ys = yr.Cells[0].Value.ToString();
        }
        catch
        {
        }

        if (HasMatch(xs) && !HasMatch(ys)) return -1;
        else if (!HasMatch(xs) && HasMatch(ys)) return 1;
        else return defaultComparer.Compare(xs, ys);
    }

【问题讨论】:

    标签: c# .net winforms sorting datagridview


    【解决方案1】:

    这只有在您自己填充网格而不是将其绑定到数据库时才有可能。

    DataGridViewColumn.SortMode 设置为Programmatic

    使用DataGridView.Sort 强加这样的比较器:

    public class MatchComparer : IComparer  {
         int IComparer.Compare(object x, object y)  {
             if (HasMatch(x) && !HasMatch(y)) return -1;
             else if (!HasMatch(x) && HasMatch(y)) return 1;
             else return defaultComparer.Compare(x, y);
         }
    
         private bool HasMatch(object x) {
             return x is string && ((string)x).StartsWith("comp");
         }
    
         private static IComparer defaultComparer = new CaseInsensitiveComparer();
    }
    

    【讨论】:

    • 代码有一些编译错误..实际上有很多错误。 IComparer 需要指定类型,defaultComparer.compare 不以对象为参数,defaultComparer 不能赋值 CaseInsensitiveComparer。
    • 没关系,只要我包含集合命名空间,它就可以工作!
    • @SokwhanHuh - 就是这样。我只是编辑了一些错别字,最重要的是调用defaultComparer时交换的参数。
    • 如果我没记错的话,这只会对具有指定列的行进行排序。我需要对整行进行排序。 (我将第一列标记为“ID”,其余列只是描述所提到的 ID 的条目。如果仅对 ID 进行排序而没有排序行后面的项目,那将变得毫无意义)
    • @SokwhanHuh - 这对一个网格进行排序。没有办法对网格中的列进行相互独立的排序。
    猜你喜欢
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    • 2022-10-19
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多