代码之家  ›  专栏  ›  技术社区  ›  Hardik

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

  •  2
  • Hardik  · 技术社区  · 9 年前

    我想在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. 如何在此处实现升序或降序 (我的意思是,当我第一次单击时,它将执行升序,而当第二次单击同一列时,它应该需要执行降序)

    非常感谢您的建议和帮助。

    5 回复  |  直到 9 年前
        1
  •  2
  •   Sinatr    9 年前

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

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

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

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

        2
  •  2
  •   Lars Kristensen    9 年前

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

    这应该可以做到:

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

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

        3
  •  2
  •   MakePeaceGreatAgain    9 年前

    您必须将字符串转换为整数值,因为字符串的顺序不同(按字典顺序) 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 如果按降序排列。

        4
  •  0
  •   makison    9 年前

    更新了问题#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));
    
        5
  •  0
  •   Hardik    9 年前

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

    1.创建的列表包含与columns dataproperty相同的列。

    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.ColumnHeaderMouseClick事件和订单函数的编写代码

    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());