简体   繁体   English

排序清单 <TextBox> 数值C#

[英]Sorting List<TextBox> Numerically C#

I have these TextBoxes labeled as tb_class# and # = 1-10 我有这些TextBoxes标记为tb_class## = 1-10

So far this is the function I have 到目前为止,这是我所拥有的功能

    private List<TextBox> GetCustomClasses()
    {
        List<TextBox> tb = new List<TextBox>();
        foreach (Control con in gb_customClasses.Controls)
            if (con.Name.Contains("tb_class"))
                tb.Add(con as TextBox);
        return tb.OrderByDescending(x => x.Name.Replace("tb_class", "")).ToList();
    }

The output looks like this: 输出看起来像这样:

9
8
7
6
5
4
3
2
10
1

I could add a check for this, but I want it to go in perfect order. 我可以为此添加一张支票,但我希望它能以完美的顺序进行。 For those wondering gb_customClasses is a groupbox . 对于那些想知道gb_customClasses是一个groupbox

Solved! 解决了! Final code: 最终代码:

    private List<TextBox> GetCustomClasses()
    {
        List<TextBox> tb = new List<TextBox>();
        foreach (Control con in gb_customClasses.Controls)
            if (con.Name.Contains("tb_class"))
                tb.Add(con as TextBox);
        return tb.OrderByDescending(x => int.Parse(x.Name.Replace("tb_class", ""))).ToList();
    }

I didn't even think about adding int.Parse 我什至没有考虑添加int.Parse

You have to convert it to an int , here's a LINQ only approach: 您必须将其转换为int ,这是仅LINQ的方法:

private List<TextBox> GetCustomClasses()
{
    return gb_customClasses.Controls.OfType<TextBox>()
        .Where(txt => txt.Name.StartsWith("tb_class"))
        .OrderByDescending(txt => int.Parse(txt.Name.Substring("tb_class".Length)))
        .ToList();
}

You must make a numerical sorting, rather than lexicographic. 您必须进行数字排序,而不是按字典排序。 Try this: 尝试这个:

return tb.OrderByDescending(x => int.Parse(x.Name.Replace("tb_class", ""))).ToList();

Note, you might not have to call .ToList() , depending on your case. 注意,根据情况,您可能不必调用.ToList() Returning an IEnumerable<TextBox> instead might be useful - so do check that out. 相反,返回IEnumerable<TextBox>可能会很有用-因此请检查一下。


Don't be scared to use the Tag property to store some extra information on your controls! 不要害怕使用Tag属性在控件上存储一些额外的信息! This solution is somewhat nicer: 这个解决方案更好一些:

return tb.OrderByDescending(x => (int)x.Tag);

or 要么

return tb.OrderByDescending(x => ((MyClass)x.Tag).Index);

You just have to make sure you add an appropriate Tag for any TextBox you add to gb_customClasses.Controls . 您只需要确保为添加到gb_customClasses.Controls任何TextBox添加适当的Tag I would tend towards this approach if the controls are dynamically created (then tagging is easy, and naming not even a must) 如果控件是动态创建的,我会倾向于这种方法(然后标记很容易,甚至都没有必要命名)

You're sorting them alphabetically, change your return statement to: 您按字母顺序对其进行排序,将return语句更改为:

return tb.OrderByDescending(x => Int32.Parse(x.Name.Replace("tb_class", ""))).ToList();

In order to get the list sorted numerically 为了使列表按数字排序

You should be comparing them as numbers, and not strings: 您应该将它们比较为数字,而不是字符串:

return tb.OrderByDescending(x => Convert.ToInt32(x.Name.Replace("tb_class", ""))).ToList();

Adding that little bit converts the name where you removed the tb_class from a string to an int. 再加上一点点,就可以将您从字符串中删除tb_class的名称转换为int。

modify to 修改为

OrderByDescending(x => Convert.ToInt32(x.Name.Replace("tb_class", ""))) OrderByDescending(x => Convert.ToInt32(x.Name.Replace(“ tb_class”,“”))))

I have these TextBoxes labeled as "tb_class#" and # = 1-10 我将这些文本框标记为“ tb_class#”,并且#= 1-10

With such encoding, you can utilize the fact that numbers with more digits are bigger, and also LINQ sort is stable . 通过这种编码,您可以利用以下事实:具有更多数字的数字更大,并且LINQ排序也是稳定的 In other words, simply order first by the text length, then by the text: 换句话说,只需先按文本长度排序,然后再按文本排序:

return tb.OrderByDescending(x => x.Name.Length).ThenByDescending(x => x.Name).ToList();

This might work: 这可能起作用:

private List<TextBox> GetCustomClasses()
{
    List<TextBox> tb = new List<TextBox>();

    List<String> indexes = new List<string>();

    //  N.B. A more conservative implementation might want to go for an unsigned 
    //  64-bit thing here. Just in case you run into a really big GroupBox.
    //  
    //  **WARNING** Due to Brexit, UK compilers will be changing to base 12, which 
    //  may adversely affect the performance of this loop. Also keep an eye out for 
    //  unpredictable fluctuations in the exchange rate with UK integers. 

    for (String i = "0"; Int32.Parse(i) < 0x7fffffff; i = (Int32.Parse(i) + 1).ToString())
    {
        indexes = indexes.Union(new string[] { i }).ToList();
    }

    var arrayOfIndexes = indexes.ToArray();

    //  Leave room for null terminator
    var reordered = new TextBox[gb_customClasses.Controls.Count + 1];

    foreach (Control con in gb_customClasses.Controls)
        if (con.Name.Contains("tb_class"))
            reordered[arrayOfIndexes.ToList().IndexOf(con.Name.Replace("tb_class", ""))] = con as TextBox;

    return reordered.ToList();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM