对列表进行排序<>在 C# 中使用 linq

本文关键字:linq 列表 排序 | 更新日期: 2023-09-27 18:34:51

我想在Datagridview ColumnHeaderMouseClick下做"排序"。增加或减少应该是自动的,选定的列值是自动的。

浏览了许多网站并尝试了一些选项,但我无法实现我的目标。

private void lst_Install_Item_Main_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    try
    {
        DataGridViewColumn newColumn = lst_Install_Item_Main.Columns[e.ColumnIndex];
        List<test> temp = (List<test>)lst_Install_Item_Main.DataSource;
        //var newList = temp.OrderBy(m => m.feet).ToList();
        //var newList = temp.AsQueryable().OrderBy(m => m.feet).ToList();
        temp.Sort((m1, m2) => m1.feet.CompareTo(m2.feet));
        lst_Install_Item_Main.DataSource = temp;
        lst_Install_Item_Main.Refresh();
    }
    catch (Exception ex)
    {
        MessageBox.Show("There was an error bringing sorting 'n" + ex.Message, "Testing", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

上面的代码"排序"了"英尺"列上的列表,但

  1. 我想传递用户单击的列名,可以吗?

我有这样的输入(1', 21', 123', 5', 10'(上面的代码对列表进行排序,如>>(1'、10'、123'、21'、5'(

  1. 但是我想要像>>这样的输出(1',5',10',21',123'(这可能实现吗?

  2. 如何在此处实现升序或降序(我的意思是,当我第一次单击时,它将执行升序,而第二次单击同一列时,它应该需要执行降序(

您的建议帮助将不胜感激。

对列表进行排序<>在 C# 中使用 linq

如果您没有负值,那么要根据需要进行排序,您需要将值解析为数字或简单地填充它们:

temp.Sort((m1, m2) => m1.feet.PadLeft(2).CompareTo(m2.feet.PadLeft(2)));

当比较字符串"1""5""10"时,这将比较" 1"" 5""10"(注意空格,小于0个字符(,使它们按正确的顺序排序。

确保选择足够大的数字以覆盖最长数字的填充。

您需要

feet的值排序为整数。为此,您首先需要删除英尺符号 ( ' (,然后将值解析为int(暂时,该值仍存储为字符串(。

这应该可以解决问题:

temp.Sort((m1, m2) => int.Parse(m1.feet.Replace("'", "")).CompareTo(int.Parse(m2.feet.Replace("'", ""))));

此外,我建议您在网格中显示值时不要将英尺符号存储在值中,而是使用某种格式来包含它。这样,每次都需要使用这些值时,您都可以避免此类转换和比较。

您必须

将字符串转换为整数值,因为字符串的顺序不同(按字典顺序10排在2之前(。此外,由于您的输入包含'字符,因此您必须先使用 String.Trim('''') 删除它们。

temp.Sort((m1, m2) => Convert.ToInt32(m1.feet.Trim('''')).CompareTo(Convert.ToInt(m2.feet.Trim(''''))));

或者您也可以使用Linq-OrderBy

temp = temp.OrderBy(x => Convert.ToInt32(x.feet.Trim(''''))).ToList();

如果按降序排列,则OrderByDescending

针对问题 # 3 进行了更新,添加了排序顺序的触发器

我建议您以这种方式使用ICoparer

public class TestComparer : IComparer<test>
{
    bool isAscending;
    public TestComparer(bool isAscendingOrder)
    {
        isAscending = isAscendingOrder;
    }
    int IComparer<test>.Compare(test a, test b)
    {
        int c1 = IntFromStr(a.feet);
        int c2 = IntFromStr(b.feet);
        int res;
        res = (c1 > c2) ? 1 : (c1 < c2) ? -1 : 0;
        return isAscending ? res : -res;
    }
    int IntFromStr(string s)
    {
        int result;
        return (int.TryParse(s.Replace("'", ""), out result)) ? result : int.MaxValue;
    }
}

这个比较器会将无效的项目移动到排序列表的末尾,您也可以轻松更改排序行为,您将像下面这样调用它

    List < test > lst = new List<test>();
    // It will be your property to Trigger value each time you click
    // (sortOrderTrigger = !sortOrderTrigger)
    bool sortOrderTrigger = true;
    lst.Add(new test { feet = "1'" });
    lst.Add(new test { feet = "21'" });
    lst.Add(new test { feet = "123'" });
    lst.Add(new test { feet = "5'" });
    lst.Add(new test { feet = "10'" });
    lst.Add(new test { feet = "15'" });
    lst.Add(new test { feet = "jj'" });
    lst.Add(new test { feet = "ff'" });
    lst.Sort(new TestComparer(sortOrderTrigger));

感谢您的所有帮助和指导。我已经将我的要求固定如下,希望这对像我这样的人有所帮助:)

1. 创建的列表包含与列数据属性相同的列。

public class sortList
        {
            public string Layer { get; set; }
            public string mlenth { get; set; }
            public string diameter { get; set; }
            public string subtypecd { get; set; }
            public string coatingtype { get; set; }
            public string year { get; set; }
            public string gisid { get; set; }
            public string taxdistrict { get; set; }
            public string lengthsource { get; set; }
            public string shapelen { get; set; }
            public string feet { get; set; }    
            public sortList()
            {
                this.Layer = ListSortDirection.Ascending.ToString();
                this.mlenth = ListSortDirection.Ascending.ToString();
                this.feet = ListSortDirection.Ascending.ToString();
                this.diameter = ListSortDirection.Ascending.ToString();
                this.subtypecd = ListSortDirection.Ascending.ToString();
                this.coatingtype = ListSortDirection.Ascending.ToString();
                this.year = ListSortDirection.Ascending.ToString();
                this.gisid = ListSortDirection.Ascending.ToString();
                this.taxdistrict = ListSortDirection.Ascending.ToString();
                this.lengthsource = ListSortDirection.Ascending.ToString();
                this.shapelen = ListSortDirection.Ascending.ToString();
            }
        }

2. 在列标题鼠标点击事件和排序函数上编写代码

private void lst_Install_Item_Main_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            try
            {
                //Get Column which clicked
                DataGridViewColumn newColumn = lst_Install_Item_Main.Columns[e.ColumnIndex];
                //Get Values from DataGrid
                List<test> temp = (List<test>)lst_Install_Item_Main.DataSource;
                //Get the sorting order for that column
                string orderby = GetOrder(newColumn.DataPropertyName);
                if (orderby == ListSortDirection.Ascending.ToString()) //Ascending
                {
                    if (newColumn.DataPropertyName == "feet") //Feet column sort with double value and required trim
                    {
                        temp = temp.OrderBy(x => Convert.ToDouble(x.feet.Trim(''''))).ToList();
                    }
                    else if (newColumn.DataPropertyName == "shapelen") //Shapelen column sort with double value and required trim
                    {
                        temp = temp.OrderBy(x => Convert.ToDouble(x.shapelen.Trim(''''))).ToList();
                    }
                    else ///other columns having string value only.
                    {
                        temp = temp.OrderBy(x => x.GetType().GetProperty(newColumn.DataPropertyName).GetValue(x, null)).ToList();
                    }
                }
                else // Descending 
                {
                    if (newColumn.DataPropertyName == "feet") //Feet column sort with double value and required trim
                    {
                        temp = temp.OrderByDescending(x => Convert.ToDouble(x.feet.Trim(''''))).ToList();
                    }
                    else if (newColumn.DataPropertyName == "shapelen")  //Shapelen column sort with double value and required trim
                    {
                        temp = temp.OrderByDescending(x => Convert.ToDouble(x.shapelen.Trim(''''))).ToList();
                    }
                    else //other columns having string value only.
                    {
                        temp = temp.OrderByDescending(y => y.GetType().GetProperty(newColumn.DataPropertyName).GetValue(y, null)).ToList();
                    }
                }
                lst_Install_Item_Main.DataSource = temp;
                lst_Install_Item_Main.Refresh();
            }
            catch (Exception ex)
            {
                MessageBox.Show("There was an error while sorting 'n" + ex.Message, "Closeout Calculator", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private string GetOrder(string columnName)
        {
            //Store the each coulmn(Ascending/Descending) values to make it dynamic 
            string ord = sortOrder[0].GetType().GetProperty(columnName).GetValue(sortOrder[0], null).ToString();
            if (ord == ListSortDirection.Ascending.ToString())
            {
                sortOrder[0].GetType().GetProperty(columnName).SetValue(sortOrder[0], ListSortDirection.Descending.ToString(), null);
            }
            else
            { sortOrder[0].GetType().GetProperty(columnName).SetValue(sortOrder[0], ListSortDirection.Ascending.ToString(), null); }
            return ord;
        }

3. 排序器列表初始化并在构造函数中声明 obj。

Private List<sortList> sortOrder = new List<sortList>();
sortOrder.Add(new sortList());