【问题标题】:display full text in a label in c#在c#的标签中显示全文
【发布时间】:2013-01-04 08:41:45
【问题描述】:

我在windows form 中有一个label 控件。我想在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 个字符分割。

还有其他方法可以实现吗?

【问题讨论】:

  • 我看到了您的问题 - 最后一点文字没有显示出来。我建议您阅读下面的 cmets,您从中获取了 Split 方法,答案就在那里。 stackoverflow.com/questions/1450774/…
  • 有没有办法用全文分词,不带连字符(-)?
  • 是的,您需要实现一个 Word-Wrap 方法。看起来史蒂夫提供了一个,我会在几分钟后发布我使用的那个。

标签: c# .net string winforms substring


【解决方案1】:

我不知道你是否会接受不使用 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);

【讨论】:

  • 感谢您,但请注意,这不是一个完整的解决方案。如果碰巧word 包含超过 32 个字符,那么上面的代码就会出现问题
  • 好吧,事实证明这比我想象的要复杂一些,但现在它似乎也可以正确拆分长度> 32的子字符串
【解决方案2】:

你可以试试

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")

【讨论】:

  • 异常:索引和长度必须引用字符串中的位置。参数名称:长度
  • 有没有办法用全文分词,不带连字符(-)?
  • Arshad,它是可行的,这将是一个更复杂的算法,如果一行太长而没有空格,你希望行为是什么?
  • @ Bob Vale,如果可能的话,我会尽量不使用连字符。
【解决方案3】:

你必须在下面的计算中取结果的上限

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

【讨论】:

  • 异常:索引和长度必须引用字符串中的位置。参数名称:长度
  • 有没有什么办法可以不使用连字符 (-) 的全文工作?
【解决方案4】:

将我的答案混入其中。这有效:

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

【讨论】:

  • 有没有办法用全文分词,不带连字符(-)?
【解决方案5】:

试试这个..

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;
 }

希望对你有帮助:)

【讨论】:

  • 有没有办法用全文分词,不带连字符(-)?
猜你喜欢
  • 1970-01-01
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 2019-12-24
  • 2019-11-23
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
相关资源
最近更新 更多