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

DataGridViewで文字のはみ出し描画

環境/言語:[Wndows Vista,VB2005,.NET Framework3.5]
分類:[.NET]

いつも拝見させていただきお世話になってます。
DataGridViewに関して質問させていただきます。

ある特定のセルのみ入力されている文字を折り返しもせず
セルをはみ出させて表示させたいのですが可能でしょうか?
また、可能であればどう記述すればいいでしょうか?

5行3列の抜粋イメージです↓

|    文字A    |
―――――――――――――
|    文字B    |
―――――――――――――
|   |   |文字E|
|文字C|文字D|文字F|
|   |   |文字G|
―――――――――――――

文字A、Bは実際は2列目の幅を超える文字列となっているので
折り返さないで表示すると「...」で省略されてしまっています。
これを省略、折り返しせず、1列目、3列目にまたがってでも1行で
表示させたいのです。

拙い質問文かもしれませんが
ご教授のほど、よろしくお願いします。
■No25114に返信(ポッチたまさんの記事)
> ある特定のセルのみ入力されている文字を折り返しもせず
> セルをはみ出させて表示させたいのですが可能でしょうか?
下記のような形式でよければ何度か実装した事がありますが、プロパティ一発とはいかず、
DataGridView の場合、『描画処理を自前で処理する』必要があるはずです。
http://www.vb-user.net/junk/200704031257/DataGridView.png

そのため、実装には Graphics クラスの使い方を理解する必要があります。


> また、可能であればどう記述すればいいでしょうか?
コード例は省略して、まずは考え方から説明させてもらいますが、この場合、
CellPaint イベントを利用する(または、OnCellPainting メソッドを実装する)ことで実現出来ます。


先の 5 行 3 列の DataGridView の例でいえば、
   0   1   2  
 ┏━━━┷━━━┷━━━┓
0┃    文字A    ┃
 ╂───────────┨
1┃    文字B    ┃
 ╂───┬───┬───┨
2┃   │   │文字E┃
 ┨   │   ├───┨
3┃文字C│文字D│文字F┃
 ┨   │   ├───┨
4┃   │   │文字G┃
 ┗━━━┷━━━┷━━━┛
に対して、CellPainting を
 0行目、0〜2列目の CellPainting … (0, 0)-(0, 2) の範囲に「文字A」を描画
 1行目、0〜2列目の CellPainting … (1, 0)-(1, 2) の範囲に「文字B」を描画
 2〜4行目、0列目の CellPainting … (2, 0)-(4, 0) の範囲に「文字C」を描画
 2〜4行目、1列目の CellPainting … (2, 1)-(4, 1) の範囲に「文字D」を描画
 2行目、2列目   の CellPainting …        (2, 2) の範囲に「文字E」を描画
 3行目、2列目   の CellPainting …        (3, 2) の範囲に「文字F」を描画
 4行目、2列目   の CellPainting …        (3, 2) の範囲に「文字G」を描画
のように実装します。
なお (2, 2)-(4, 2) の範囲は、自前で描画せず、標準の動作のままでも構いません。

また、マージされたセルの選択方法によっては、これを 3 行 3 列とみなして
   0   1   2  
 ┏━━━┷━━━┷━━━┓
0┃    文字A    ┃
 ╂───────────┨
1┃    文字B    ┃
 ╂───┬───┬───┨
 ┃   │   │文字E┃
2┃文字C│文字D│文字F┃
 ┃   │   │文字G┃
 ┗━━━┷━━━┷━━━┛
それぞれの CellPainting イベントを
 (0, x) の CellPainting … (0, 0)-(0, 2) の範囲に「文字A」を描画
 (1, x) の CellPainting … (1, 0)-(1, 2) の範囲に「文字B」を描画
 (2, 0) の CellPainting …        (2, 0) の範囲に「文字C」を描画
 (2, 1) の CellPainting …        (2, 1) の範囲に「文字D」を描画
 (2, 2) の CellPainting … (2, 2) の範囲に「文字E」「文字F」「文字G」の 3 行を描画
という処理を実装する事になります。
この場合、(2, 0)および(2, 1)については、標準の描画処理に任せておいても構いません。


なお、CellPainting イベントは、個々のセルごとに呼び出されます。
描画先となる領域は、自セルだけであれば e.CellBounds で得られますが、
0行目 1 行目のように、隣り合うセル領域も測定しなければならない場合には
DataGridView.Columns(列番号).Width を併用して、隣のセル幅を求めて算出します。

領域が分かったら、その領域に対して、
 背景の塗りつぶし → テキストの描画 → 罫線の描画
を行っていけば OK です。選択されているセルの場合、描画色が異なることに注意してください。

描画処理の基本手順については、ここ どぼん! さんのサイトが参考になるでしょう。
http://dobon.net/vb/dotnet/graphics/


なお、描画開始位置は基本的に、マージされたセルの左上を原点として行う事になると思います。
テキストの水平中央寄せ/垂直中央寄せなどの位置制御は、Graphics.DrawString メソッドの引数に、
StringFormat を指定することで行えます。列幅が短い場合の長い文字列の描画方法を
省略記号[...]で表現するのか、文字単位で打ち切るのか、折り返すのかといった制御も
Graphics.DrawString の引数指定で行えますので、ヘルプで確認してみてください。
■No25118に返信(魔界の仮面弁士さんの記事)

>魔界の仮面弁士さま
ご返答頂きありがとうございます。
様々な質問への回答、拝見しいつも勉強させて頂いてます。

>DataGridView の場合、『描画処理を自前で処理する』必要があるはずです。
やはり自前描画となってしまうんですね。

今現在、CellPaintingイベント時にe.AdvancedBorderStyleプロパティにより
罫線の描画は実装していたので、そこに今回教えていただいた
Graphicsクラスの実装を盛り込んで実現していこうと思います。

Graphicsクラスに関してもう少し自分で調査し
実装方法を試行錯誤してみたいと思います。
各セルのCellPaintingイベントにGraphicsで
実装出来ました。

セルが選択されると描画が消えてしまったりしてますが
そこはまた自分でいろいろ考えようと思います。

魔界の仮面弁士さま、
ご教授して頂きありがとうございました。
解決済み!

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