SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

DataGridViewのカスタム列タイプの作成

DataGridViewのセル内にグラフを描画する

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード サンプルソース (56.0 KB)

配置の処理

 このようなプログラミングには、当然ながら、細かい配置処理が伴います。最長の横棒と各横棒の長さの比率、最長の横棒に使用できるスペース、関連テキスト用に残すべきスペースなどを計算する必要があります。

 この問題を解決するには、列のすべての値の最大値を取得する必要があります。これは親列で処理できます。親列への参照は、セルのOwningColumnプロパティを使用して取得します。次のコードを追加します(この時点では、親列のCalcMaxValueメンバとMaxValueメンバは当然ながらまだ実質的な処理は行いません)。

Visual Basic
' Get the parent column and the maximum value:
   Dim parent As DataGridViewBarGraphColumn = _
      CType(Me.OwningColumn, DataGridViewBarGraphColumn)
   parent.CalcMaxValue()
   Dim maxValue As Long = parent.MaxValue
C#
// Get the parent column and the maximum value:
   DataGridViewBarGraphColumn parent =
     (DataGridViewBarGraphColumn)this.OwningColumn;
   parent.CalcMaxValue();
   long maxValue = parent.MaxValue;

 ここで、列のInheritedStyleプロパティを使用して列のフォントも取得できます。

Visual Basic
Dim fnt As Font = parent.InheritedStyle.Font
C#
Font fnt = parent.InheritedStyle.Font;
編集部注
 DataGridViewコントロールのセルと列のスタイルの継承は、非常に綿密にサポートされています。詳細については、MSDNヘルプトピック「WindowsフォームDataGridViewコントロールでのセルのスタイル」を参照してください。

 各セルで使用可能なスペースの量を計算するには、最大値のテキストの幅を把握しておく必要があります。この幅がわかれば、各セルの横棒の最大サイズを計算できます。必要な値はGraphics.MeasureStringメソッドで取得できるので、これらの値を計算する次のコードを追加します。

Visual Basic
Dim maxValueSize As SizeF = _
   graphics.MeasureString(maxValue.ToString, fnt)
Dim availableWidth As Single = _
   cellBounds.Width - maxValueSize.Width - _
   SPACER - (HORIZONTALOFFSET * 2)
C#
SizeF maxValueSize =
   graphics.MeasureString(maxValue.ToString(), fnt);
float availableWidth =
   cellBounds.Width - maxValueSize.Width -
   SPACER - (HORIZONTALOFFSET * 2);

 横棒に使用できる幅を計算したら、使用可能なスペースに収まるように、現在のセルの値と最大値の比率を使用して、現在のセルの横棒の幅(長さ)を計算できます。これを処理する次のコードを追加します。

Visual Basic
cellValue = CDec((cellValue / maxValue) * _
   availableWidth)
C#
cellValue = Convert.ToDecimal(
  (Convert.ToDouble(cellValue) / maxValue) *
  availableWidth);

 これで内容を描画する準備ができました。次のコードを追加してください。このコードでは、横棒のサイズを計算し、横棒を赤いブラシで描画します。

Visual Basic
' Draw the bar, truncating to fit in the space 
' you've got in the cell:
Const VERTOFFSET As Integer = 4
Dim newRect As New RectangleF( _
   cellBounds.X + HORIZONTALOFFSET, _
   cellBounds.Y + VERTOFFSET, _
   cellValue, _
   cellBounds.Height - (VERTOFFSET * 2))
graphics.FillRectangle(Brushes.Red, newRect)
C#
const int VERTOFFSET = 4;
RectangleF newRect = new RectangleF(
   cellBounds.X + HORIZONTALOFFSET,
   cellBounds.Y + VERTOFFSET,
   Convert.ToSingle(cellValue),
   cellBounds.Height - (VERTOFFSET * 2));
graphics.FillRectangle(Brushes.Red, newRect);

 次に、テキストを描画するコードを追加します。

Visual Basic
' Get the text to draw and calculate its width:
Dim cellText As String = formattedValue.ToString()
Dim textSize As SizeF = _
   graphics.MeasureString(cellText, fnt)
' Calculate where text would start:
Dim textStart As PointF = _
   New PointF( _
   HORIZONTALOFFSET + cellValue + SPACER, _
   (cellBounds.Height - textSize.Height) / 2)
   
' Calculate the correct color:
Dim textColor As Color = _
   parent.InheritedStyle.ForeColor
If (cellState And _
   DataGridViewElementStates.Selected) = _
   DataGridViewElementStates.Selected Then
   textColor = parent.InheritedStyle.SelectionForeColor
End If
   
' Draw the text:
Using brush As New SolidBrush(textColor)
   graphics.DrawString(cellText, fnt, brush, _
      cellBounds.X + textStart.X, _
      cellBounds.Y + textStart.Y)
End Using
C#
string cellText = formattedValue.ToString();
SizeF textSize = 
   graphics.MeasureString(cellText, fnt);
   
//  Calculate where text would start:
PointF textStart = new PointF(
   Convert.ToSingle(HORIZONTALOFFSET + 
   cellValue + SPACER), 
   (cellBounds.Height - textSize.Height) / 2);
   
//  Calculate the correct color:
Color textColor = parent.InheritedStyle.ForeColor;
if ((cellState & 
   DataGridViewElementStates.Selected) == 
   DataGridViewElementStates.Selected)
{
   textColor = parent.InheritedStyle.SelectionForeColor;
}
// Draw the text:
using (SolidBrush brush = 
new SolidBrush(textColor))
{
  graphics.DrawString(cellText, fnt, brush, 
    cellBounds.X + textStart.X, 
    cellBounds.Y + textStart.Y);
}

 このコードでは、まずテキストの開始位置の計算と新しいFontオブジェクトの作成を行っています。このコードの次の部分は、新しいフォントでのテキストの幅を計算しています。

Visual Basic
Dim cellText As String = formattedValue.ToString()
Dim textSize As SizeF = _
   graphics.MeasureString(cellText, fnt)
C#
string cellText = formattedValue.ToString();
SizeF textSize = 
   graphics.MeasureString(cellText, fnt);

 次の部分は、テキストの先頭がセル内のどこになるかを計算しています。横棒の幅、各種オフセット、セルとテキストの高さから計算しています。

Visual Basic
Dim textStart As PointF = _
   New PointF( _
   HORIZONTALOFFSET + cellValue + SPACER, _
   (cellBounds.Height - textSize.Height) / 2)
C#
PointF textStart = new PointF(
   Convert.ToSingle(HORIZONTALOFFSET + 
   cellValue + SPACER),
   (cellBounds.Height - textSize.Height) / 2);

 また、選択中のセルのテキストは標準のセルとは異なる表示にするため、セルが選択されているかどうかを検出し、ふさわしいテキストカラーにする必要があります。このコードの次の部分は、cellStateパラメータを使ってこれを判別しています。

Visual Basic
Dim textColor As Color = _
   parent.InheritedStyle.ForeColor
If (cellState And _
   DataGridViewElementStates.Selected) = _
   DataGridViewElementStates.Selected Then
   textColor = parent.InheritedStyle.SelectionForeColor
End If
C#
Color textColor = parent.InheritedStyle.ForeColor;
if ((cellState & 
   DataGridViewElementStates.Selected) ==
   DataGridViewElementStates.Selected)
{
   textColor = parent.InheritedStyle.SelectionForeColor;
}

 cellStateパラメータは複数の値の組み合わせになっているので、このようにAnd演算子を使用して、このパラメータに各値が設定されているかどうかを判別します。

 最後に、テキストをセル内の適切な位置に描画します。

Visual Basic
Using brush As New SolidBrush(textColor)
   graphics.DrawString(cellText, fnt, brush, _
      cellBounds.X + textStart.X, _
      cellBounds.Y + textStart.Y)
End Using
C#
using (SolidBrush brush = new SolidBrush(textColor))
{
   graphics.DrawString(cellText, fnt, brush,
      cellBounds.X + textStart.X,
      cellBounds.Y + textStart.Y);
}

次のページ
列の完成

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Ken Getz(Ken Getz)

MCW Technologies社上級顧問。プログラミング、執筆、教育に携わる。専門はVisual Studio .NETおよびVisual Basicでのツール/アプリケーション開発。『CoDe Magazine』誌の好評コラム「.Finalize()」を担当。共著にベストセラーとなった『Acce...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/1707 2007/10/04 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング