ラベルなどのコントロールで Text を設定した際、コントロールのクライアントサイズより長い文字列を指定すると、入りきらない表示部分が消えて表示されます。

後方が消えている事を示す ... を表示するには、AutoSize = false; とした上で、AutoEllipsis = true; とします。ただ、この省略表示はパス表示の場合は、一番大事なファイル名部分が消えてしまうために、あまり現実的な実装では無いんですよね。

後方が消えている事を示す ... を表示するには、AutoSize = false; とした上で、AutoEllipsis = true; とします。ただ、この省略表示はパス表示の場合は、一番大事なファイル名部分が消えてしまうために、あまり現実的な実装では無いんですよね。

そこでなんとか出来ないかと調べていたところ、Twitterにて Mitsuhito Ishino さんからこんなサイトをご紹介頂きました。
ファイルパスを人間が読みやすいように縮小する関数
このリンク先の最後の方に Label を派生して PathLabel というコントロールを作り、その中の OnPaint をオーバーライドして自前描画しているサンプルがありました。それを見ると、いきなり DrawText しているだけで、特別な処理をしているワケでは無かったのですが、よく見ると最後のパラメータに TextFormatFlags.PathEllipsis という謎の指定が!
この TextFormatFlags 列挙体は詳細はこちらで説明されていますが、その中の PathEllipsis メンバの説明に注目!
トリムされる行の中央を削除し、省略記号に置き換えます。 TextRenderer でテキストを描画するために使用する場合、ModifyString フラグが指定されていない限り、文字列は変更されません。 EndEllipsis および WordEllipsis と比較します。
この説明のトリムされる行の中央とは、ファイル名を全て表示した上で、その直前のパスを規定の範囲に収まるように省略する動作を行います。
※ 複数のレトロPCの映像出力を簡単に切り替えられます!この TextFormatFlags は表示位置の調整フラグもあります。
必要と思われる各要素は以下の通りです。
必要と思われる各要素は以下の通りです。
HorizontalCenter | 横方向にセンタリング |
VerticalCenter | 縦方向にセンタリング |
Left | 左寄せ |
Right | 右寄せ |
Top | 上寄せ |
Bottom | 下寄せ(1行のみ有効) |
EndEllipsis | 後方省略 |
PathEllipsis | パス文字列省略 |
WordEllipsis | 単語単位での後方省略 |
実は標準のコントロールにはおそらくバグがあり、AutoEllipsis = true; とすると、TextAlign が無視されて既定の位置になってしまいます。おそらく、EndEllipsis を単純にフラグとして使用しているだけだと思います。このバグの修正も加味したパスの省略表示は以下の通りです。このメソッドは Label の Paint イベントから呼び出すのを前提としていますが、殆どの場合はそのまま別のコントロールにも使用できると思います。
※ VS2022 C# 10 にて動作確認
この処理を適用してコントロールに長いパスを指定すると、このような表示となります。
// ------------------------------------------------------------- // テキストをパスと見なして省略描画する // ------------------------------------------------------------- private void PathEllipsis_Paint(object sender, PaintEventArgs e)
{ Label label = (Label)sender; #if DEBUG if (label.AutoSize) { throw new Exception("You must set " + Name + ".AutoSize = false in VS " + "Designer and assign a fix width to the PathLabel."); } #endif // パス省略&左寄せ中心 Color foreColor = label.Enabled ? label.ForeColor : SystemColors.GrayText; TextFormatFlags flags = 0 | TextFormatFlags.VerticalCenter | TextFormatFlags.Left | (label.AutoEllipsis ? TextFormatFlags.PathEllipsis : 0); // 描画する e.Graphics.Clear(label.BackColor); TextRenderer.DrawText( dc: e.Graphics, text: label.Text, font: label.Font, bounds: label.ClientRectangle, foreColor: foreColor, backColor: label.BackColor, flags: flags); }

これでようやく納得できる表示となりました。
iggy
※ パーテーションに引っ掛けてモニタを設置するアイディア賞な製品!机が広く使えます!
※ パーテーションに引っ掛けてモニタを設置するアイディア賞な製品!机が広く使えます!
コメント
コメント一覧 (2)
ところで、
TextFormatFlags flags = 0
| TextFormatFlags.VerticalCenter
| TextFormatFlags.Left
| label.AutoEllipsis ? TextFormatFlags.PathEllipsis : 0;
の部分ですが、
TextFormatFlags flags = 0
| TextFormatFlags.VerticalCenter
| TextFormatFlags.Left
| (label.AutoEllipsis ? TextFormatFlags.PathEllipsis : 0);
と括弧を付けないとエラーになりませんか。私の VS は 2017 ですが。
ほかにもいろいろなサイトの情報を見てみたのですが、私の要望としては
C:\abc\def\...\jkl
ではなく
C:\...\def\ghi\jkl
と縮めてほしかったので結局自分で作りました。
長さを調べながら一文字ずつ縮めていくという簡単なものですが。
内藤時浩
が
しました