5

我有一个label控制权windows form。我想在label. 条件是这样的:

  • 如果文本长度超过 32 个字符,它将出现在新行中。
  • 如果可能的话,用完整的单词分割,不带连字符(-)。

    到目前为止,我已经达到了以下代码:

       private void Form1_Load(object sender, EventArgs e)
        {
            string strtext = "This is a very long text. this will come in one line.This is a very long text. this will come in one line.";
            if (strtext.Length > 32)
            {              
                IEnumerable<string> strEnum = Split(strtext, 32);
                label1.Text =string.Join("-\n", strEnum);
            }         
        }
        static IEnumerable<string> Split(string str, int chunkSize)
        {
            return Enumerable.Range(0, str.Length / chunkSize)
                .Select(i => str.Substring(i * chunkSize, chunkSize));
        }
    

但问题是最后一行没有完全显示,因为它被 32 个字符分割。

还有另一种方法可以实现这一目标吗?

4

5 回答 5

2

我不知道您是否会接受不使用 linq 的答案,但这很简单:

string SplitOnWholeWord(string toSplit, int maxLineLength)
{
    StringBuilder sb = new StringBuilder();
    string[] parts = toSplit.Split();
    string line = string.Empty;
    foreach(string s in parts)
    {
        if(s.Length > 32)
        {
            string p = s;
            while(p.Length > 32)
            {
                int addedChars = 32 - line.Length;
                line = string.Join(" ", line, p.Substring(0, addedChars));
                sb.AppendLine(line);
                p = p.Substring(addedChars);
                line = string.Empty;
            }
            line = p;
        }
        else
        {
            if(line.Length + s.Length > maxLineLength)
            {
                sb.AppendLine(line);
                line = string.Empty;
            }
            line = (line.Length > 0 ? string.Join(" ", line, s) : s);
        }
    }
    sb.Append(line.Trim());
    return sb.ToString();
}

打电话给

string result = SplitOnWholeWord(strtext, 32);

可以轻松地将其转换为扩展方法:

将上面的代码放在一个单独的文件中,并创建一个静态类

public static class StringExtensions
{
     public static string SplitOnWholeWord(this string toSplit, int maxLineLength)
     {
          // same code as above.....
     }

}

并以这种方式调用它:

string result = strtext.SplitOnWholeWord(32);
于 2013-01-21T10:45:01.680 回答
1

试试这个..

string strtext = "This is a very long text. this will come in one line.This is a very long text. this will come in one line.";
if (strtext.Length > 32)
{
   IEnumerable<string> strEnum = Split(strtext, 32);
   string a = string.Join("-\n", strEnum);
   if ((strtext.Length % 32)>0)
   {
      string lastpart = strtext.Substring(((strtext.Length / 32) * 32));
      a = a + "-\n" + lastpart;
   }
   label1.Text=a;
 }

希望能帮助到你 :)

于 2013-01-21T10:26:00.090 回答
0

您必须在以下计算中取结果的上限

str.Length / chunkSize

现在它将返回结果的整数部分并忽略是否有任何提醒,因此如果您在 str 中有 120 个字符,并且您的块大小为 50,则上述计算将给出 result = 2,您将其用作块,这是错误的,你需要 3 在这里。

为确保您的除法工作正常,您可以在 str.length 中添加额外的长度

使用以下代码:

static IEnumerable<string> Split(string str, int chunkSize)
{
    return Enumerable.Range(0, (str.Length+chunkSize-1) / chunkSize)
        .Select(i => str.Substring(i * chunkSize, (str.length-(i*chunkSize))>=chunkSize? chunkSize:str.length-(i*chunkSize)));
}
于 2013-01-21T10:12:29.747 回答
0

你可以试试

static IEnumerable<string> Split(string str, int chunkSize)
    {
        var count = str.Length / chunkSize;
        var result=Enumerable.Range(0, count)
            .Select(i => str.Substring(i * chunkSize, chunkSize));
        var end = count * chunkSize;
        if (end < str.Length) {
            result = result.Concat(str.Substring(end, str.Length - end));
        }
        return result;
    }

或者

static IEnumerable<string> Split(string str, int chunkSize)
    {
       for (var i=0; i<str.Length; i+=chunkSize) {
           yield return str.Substring(i, Math.Min(str.Length-i, chunkSize));
       }
    }      

编辑:合理的分裂,评论后

static IEnumerable<string> split(string str,int chunkSize) {
    var words=str.Split(' ');
    var line=new StringBuilder(chunkSize);
    for (var i=0; i<words.Length;i++) {
        var word=words[i];
        if (line.Length + word.Length + 1 > chunkSize) {
            if (line.Length == 0) {
                for(var x=0;x<word.Length/chunkSize;x++) {
                    yield return word.Substring(x*chunkSize,chunkSize);
                }
                var remainder = word.Length % chunkSize;
                if (remainder>0) {
                    line.Append(word.Substring(word.Length-remainder, remainder));
                }
            } else {
                yield return line.ToString();
                line.Clear();
                i--; // Force reprocessing this word
            }
        }  else {
            if (line.Length>0) {
                line.Append(" ");
            }
            line.Append(word);
        }
    }
}

不要忘记改变你string.Join("-\n")的存在string.Join("\n")

于 2013-01-21T10:13:19.273 回答
0

把我的答案混在一起。这有效:

static IEnumerable<string> Split(string str, int chunkSize) {
    int difference = (str.Length % chunkSize);
    int count = str.Length / chunkSize;
    return Enumerable.Range(0, count + 1)
        .Select(i => str.Substring(i * chunkSize, i == count ? difference : chunkSize));
}
于 2013-01-21T10:29:48.860 回答