簡體   English   中英

每行的列表框字符數限制

[英]Listbox character limit per line

我的Windows窗體應用程序中有一個列表框,顯示了很長的文本。 由於文本太長,用戶必須使用水平滑塊來檢查其余文本。

因此,我想限制每行的列表框字符。 每50個字符應轉到下一行,因此用戶不必使用滑翔機。

因為文本源是Sql數據庫,所以我不能放“換行”。

我的代碼基本上是這樣的:

listbox1.items.add(dbRead["LongText"]); // dbRead = SqlDataReader

所以我必須編輯列表框本身。 我檢查了一下,但沒有找到。 我還嘗試為每個50個字符的listbox.items.add("")等查找一個事件,如更改文本時。我仍然與語法無關。

有什么建議么 ?

您可以編寫一個擴展方法( SplitByLength ),如下所示

var input = "I have a listbox in my windows form application that shows quite long texts. Since texts are so long, user have to use the horizontal slider for check the rest of text.\nSo, I want to limit listbox character per line. For every 50 char it should go to next row, so user won't have to use glider.";
var lines = input.SplitByLength(50).ToArray();
listBox1.Items.AddRange(lines);

public static partial class MyExtensions
{
    public static  IEnumerable<string> SplitByLength(this string input, int maxLen)
    {
        return Regex.Split(input, @"(.{1," + maxLen + @"})(?:\s|$)")
                    .Where(x => x.Length > 0)
                    .Select(x => x.Trim());
    }
}

- - - - - 編輯 - - - - -

在tinstaafl發表評論后,似乎必須進行編輯

var input = "I have a listbox in my windows form application that shows quite long texts. Since texts are so long, user have to use the horizontal slider for check the rest of text.\nSo, I want to limit listbox character per line. For every 50 char it should go to next row, so user won't have to use glider.";
input = String.Join(" ", Enumerable.Repeat(input, 100));

var t1 = Measure(10, () =>
{
    var lines = input.SplitByLength_LB(50).ToArray();
});

var t2 = Measure(10, ()=>
{
    var lines = input.SplitByLength_tinstaafl(50).ToArray();
});

long Measure(int n,Action action)
{
    action(); //JIT???
    var sw = Stopwatch.StartNew();
    for (int i = 0; i < n; i++)
    {
        action();
    }
    return sw.ElapsedMilliseconds;
}

public static partial class MyExtensions
{
    public static  IEnumerable<string> SplitByLength_LB(this string input, int maxLen)
    {
        return Regex.Split(input, @"(.{1," + maxLen + @"})(?:\s|$)")
                    .Where(x => x.Length > 0)
                    .Select(x => x.Trim());
    }

    public static IEnumerable<string> SplitByLength_tinstaafl(this string input, int maxLen)
    {
        List<string> output = new List<string>();
        while (input.Length > 0)
        {
            output.Add(new string(input.Take(maxLen).ToArray()));
            input = new string(input.Skip(maxLen).ToArray());
        }
        return output;
    }
}

我的結果與您的結果有所不同: 11毫秒。 與3384毫秒。 :)

重命名我的代碼以考慮空間。 對於可變長度的行,一些短於50個字符,並且換行符針對空格進行了調整,我發現性能非常接近。 它們在1000個字符串上都在15到25毫秒之間。 盡管regex的確確實表現得更快。 這是我使用的代碼:

public static partial class MyExtensions
{
    public static IEnumerable<string> SplitByLength_LB(this string input, int maxLen)
    {
        return Regex.Split(input, @"(.{1," + maxLen + @"})(?:\s|$)")
                    .Where(x => x.Length > 0)
                    .Select(x => x.Trim());
    }
    public static IEnumerable<string> SplitByLength_tinstaafl(this string input, int maxLen)
    {
        List<string> output = new List<string>{""};

        string[] temp = input.Split("\n ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
        for(int i = 0; i < temp.Count(); i++)
        {
            if((output.Last() + " " + temp[i]).Length > 50)
            {
                output.Add(temp[i]);
            }
            else
                output[output.Count() - 1] += " " + temp[i];
        }
        return output;
    }
        return output;
    }

測試是這樣的:

        Stopwatch s1 = new Stopwatch();
        List<string> source = new List<string>();
        Random rnd = new Random();
        for(int i = 0; i < 1000; i++)
        {
            var input = "I have a listbox in my windows form application that shows quite long texts. Since texts are so long, user have to use the horizontal slider for check the rest of text. So, I want to limit listbox character per line.";
            int nextbreak = rnd.Next(20, input.Length);
            source.Add(new string(input.TakeWhile((x, y) => input.IndexOf(' ', y) <= nextbreak).ToArray()));
        }
        s1.Start();
        List<string> output = new List<string>(from s in source
                                               from p in s.SplitByLength_LB(50)
                                               select p);
        s1.Stop();
        Console.WriteLine("SplitByLength_LB\t" + s1.ElapsedMilliseconds.ToString());
        s1.Reset();
        s1.Start();
        List<string> output2 = new List<string>(from s in source
                                                from p in s.SplitByLength_tinstaafl(50)
                                                select p);
        s1.Stop();
        Console.WriteLine("SplitByLength_tinstaafl\t" + s1.ElapsedMilliseconds.ToString());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM