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

私の答えをミックスに投げ込みます。これは機能します:

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 に答える
0

次の計算では、結果の天井を取る必要があります

str.Length / chunkSize

現在、結果の整数部分が返され、リマインダーが存在する場合は無視されます。したがって、str に 120 文字があり、チャンク サイズが 50 の場合、上記の計算により、数として使用している結果 = 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 に答える