DOBON.NET DOBON.NETプログラミング掲示板過去ログ

Graphics.DrawString の折り返し処理

環境/言語:[C# .NET Framework2.0]
分類:[.NET]

Graphics.DrawStringで、改行を含まない文字列をRectangle範囲に描画し
右端からはみ出る部分の文字列を折り返しさせる場合に、
折り返された後に続くスペースはなぜか描画されないようです。

StringFormat.FormatFlagsをいろいろと試してみましたが
期待するようにはなりませんでした。
期待する結果のように描画させることは可能でしょうか。

private void panel1_Paint(object sender, PaintEventArgs e)
{
    string str = "abcdef                   vwxyz";
    Graphics g = e.Graphics;
    StringFormat sf = StringFormat.GenericDefault;
    g.DrawString(str, this.Font, Brushes.Black,
                panel1.ClientRectangle, sf);

}

期待する結果は

---------
abcdef   |
    vwxyz|
---------


結果的にはどんなにスペースを開けても以下のような感じです。
---------
abcdef   |
vwxyz    |
---------
■No26330に返信(kyuさんの記事)

2つの文字列として分けて描画してはどうですか?
または、スペースの前に改行文字を入れるという方法も考えられます。
代替案ありがとうございます。

スペースの前に改行文字をいれないとインデントされない理由が
ちょっと謎なのですが、どうもexcelなどのオートシェイプへ
文字列入力しても上記と同じような現象になるので、
これはそういう動きで普通なのかなと思われました。
ありがとうございました。
解決済み!
■No26330に返信(kyuさんの記事)
> StringFormat.FormatFlagsをいろいろと試してみましたが
> 期待するようにはなりませんでした。

TextFormatFlags.WordBreak はどうでしょうか? (TextRenderer.DrawText)
GDI ベースの描画処理になってしまいますけれども。
解決済み!
■No26334に返信(管理人さんの記事)
> または、スペースの前に改行文字を入れるという方法も考えられます。

単語単位の折り返しではなく、文字単位の折り返しにしても良いのであれば、
描画前に、各文字間にゼロ幅空白(U+200B)を挿入するという手もあります。

private void panel1_Paint(object sender, PaintEventArgs e)
{
    string str = textBox1.Text;

    str = string.Join("", Array.ConvertAll(str.ToCharArray(), 
        delegate(Char c){return c + "\x200c";}));
    StringFormat sf = StringFormat.GenericDefault;
    e.Graphics.DrawString(str, this.Font, Brushes.Black,
                panel1.ClientRectangle, sf);
}

private void textBox1_TextChanged(object sender, EventArgs e)
{
    panel1.Invalidate();
}

private void Form1_Resize(object sender, EventArgs e)
{
    panel1.Invalidate();
}
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板