DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

DataGridセル内の文字列を折り返して表示する

注意:ここで紹介している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としてビルドし、それを参照してお使いください。
VB.NET
コードを隠すコードを選択
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
C#
コードを隠すコードを選択
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 Tipsをご利用いただく際は、注意事項をお守りください。