注意:ここで紹介しているDataGridは、System.Windows.Forms名前空間のDataGrid(Windowsフォーム)です。System.Web.UI.WebControls名前空間のDataGrid(Webフォーム)ではありません。
WindowsアプリケーションでDataGridコントロールのセル内の文字列を折り返して表示するには、DataGridColumnStyleクラスの派生クラスを作成し、そのPaintメソッドをオーバーライドして、文字列を折り返して描画するようにします。
以下にその例を示します。ここでは、DataGridTextBoxColumnクラスを継承し、新しいクラス(DataGridTextBoxColumnEx)を作ります。
このDataGridTextBoxColumnExクラスを使用するには、文字列を折り返して表示したい列の列スタイルにDataGridTextBoxColumnExオブジェクトを設定します。詳しい方法は、「DataGridの列の幅を変更する」をご覧ください。
注意:VB.NETのコードでは、PropertyDescriptorを無視しています。これは、この部分のC#のコードを完全にVB.NETに変換する方法が分からないためです(分かる方がいらっしゃれば、ご報告ください)。もしVB.NETを使っており、PropertyDescriptorが必要ならば、C#のコードをDLLとしてビルドし、それを参照してお使いください。
Imports System Imports System.Drawing Imports System.Windows.Forms Imports System.Data Imports System.ComponentModel Namespace Dobon.Samples.Forms ''' <summary> ''' DataGridに文字列を折り返して表示するためのDataGridColumnStyle ''' </summary> Public Class DataGridTextBoxColumnEx Inherits DataGridTextBoxColumn '文字列を描画するマージンを指定する Private _margin As New Point(1, 2) 'Paintメソッドをオーバーライドする Protected Overloads Overrides Sub Paint( _ ByVal g As Graphics, _ ByVal bounds As Rectangle, _ ByVal [source] As CurrencyManager, _ ByVal rowNum As Integer, _ ByVal backBrush As Brush, _ ByVal foreBrush As Brush, _ ByVal alignToRight As Boolean) '表示する文字列を取得 Dim [text] As String = _ GetText(GetColumnValueAtRow([source], rowNum)) Dim sf As New StringFormat '配置を指定する Select Case Me.Alignment Case HorizontalAlignment.Left sf.Alignment = StringAlignment.Near Case HorizontalAlignment.Center sf.Alignment = StringAlignment.Center Case HorizontalAlignment.Right sf.Alignment = StringAlignment.Far End Select 'テキストの方向を指定する If alignToRight Then sf.FormatFlags = sf.FormatFlags Or _ StringFormatFlags.DirectionRightToLeft End If '背景を塗りつぶす g.FillRectangle(backBrush, bounds) Dim rectf As New RectangleF(bounds.X, bounds.Y, _ bounds.Width, bounds.Height) rectf.Inflate(-_margin.X, -_margin.Y) '文字列を描画する g.DrawString([text], DataGridTableStyle.DataGrid.Font, _ foreBrush, rectf, sf) sf.Dispose() End Sub '表示する文字列を返す 'DataGridTextBoxColumnのGetTextがprivateのため Private Function GetText(ByVal val As Object) As String If TypeOf val Is DBNull Then ' Return NullText End If If Not (Format Is Nothing) AndAlso Format.Length <> 0 _ AndAlso TypeOf val Is IFormattable Then Try Return CType(val, IFormattable).ToString(Format, FormatInfo) Catch End Try End If If Not (val Is Nothing) Then Return val.ToString() Else Return "" End If End Function End Class End Namespace
using System; using System.Drawing; using System.Windows.Forms; using System.Data; using System.ComponentModel; namespace Dobon.Samples.Forms { /// <summary> /// DataGridに文字列を折り返して表示するためのDataGridColumnStyle /// </summary> public class DataGridTextBoxColumnEx : DataGridTextBoxColumn { //文字列を描画するマージンを指定する Point _margin = new Point(1, 2); //TypeConverterを取得しておく //DataGridTextBoxColumnのtypeConverterがprivateのため private TypeConverter _typeConverter = null; public override PropertyDescriptor PropertyDescriptor { set { base.PropertyDescriptor = value; if (PropertyDescriptor != null && PropertyDescriptor.PropertyType != typeof(object)) { _typeConverter = System.ComponentModel.TypeDescriptor.GetConverter( PropertyDescriptor.PropertyType); } } } //Paintメソッドをオーバーライドする protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, Brush backBrush, Brush foreBrush, bool alignToRight) { //表示する文字列を取得 string text = GetText(GetColumnValueAtRow(source, rowNum)); StringFormat sf = new StringFormat(); //配置を指定する switch (this.Alignment) { case HorizontalAlignment.Left: sf.Alignment = StringAlignment.Near; break; case HorizontalAlignment.Center: sf.Alignment = StringAlignment.Center; break; case HorizontalAlignment.Right: sf.Alignment = StringAlignment.Far; break; } //テキストの方向を指定する if (alignToRight) sf.FormatFlags |= StringFormatFlags.DirectionRightToLeft; //背景を塗りつぶす g.FillRectangle(backBrush, bounds); RectangleF rectf = new RectangleF( bounds.X, bounds.Y, bounds.Width, bounds.Height); rectf.Inflate(-_margin.X, -_margin.Y); //文字列を描画する g.DrawString(text, DataGridTableStyle.DataGrid.Font, foreBrush, rectf, sf); sf.Dispose(); } //表示する文字列を返す //DataGridTextBoxColumnのGetTextがprivateのため private string GetText(object val) { if ((val as DBNull) != null) return NullText; if (Format != null && Format.Length != 0 && (val as IFormattable) != null) { try { return ((IFormattable) val).ToString( Format, FormatInfo); } catch { } } if (_typeConverter != null && _typeConverter.CanConvertTo(typeof(string))) { return (string) _typeConverter.ConvertTo( val, typeof(string)); } return (val != null ? val.ToString() : ""); } } }
(この記事は「.NETプログラミング研究 第28号」で紹介したものです。)