.NET TIPS

文字列や画像を無効状態で描画するには?

デジタルアドバンテージ 一色 政彦
2005/05/27

 「TIPS:画像を高品質に拡大/縮小するには?」でも示されているように、文字列や画像を描画するには、それぞれGraphicsクラス(System.Drawing名前空間)の次のメソッドを利用すればよい。

 これはWindowsフォームのユーザー・コントロールやカスタム・コントロールでも(一般的な.NET開発では)同じで、これらのコントロール上に文字列や画像を描画する際にはDrawStringメソッドやDrawImageメソッドを用いればよい。

 ただし、コントロールを無効化している場合(EnabledプロパティをFalseに設定する)には注意が必要となる。本稿では、無効化されたコントロールに文字列や画像を正しく描画するための方法を紹介する。

無効状態に見えないコントロール

 Windows OSの一般的なユーザー・インターフェイスでは、無効化されたコントロールに描画されている文字列や画像はグレー・アウトした状態(=グレー色)で表示される。

 しかしDrawStringメソッドやDrawImageメソッドで独自の描画を加えた場合、これらはコントロールのEnabledプロパティをFalseに変更しただけでは、グレー・アウトした状態で表示されるような仕様にはなっていない。そのため、(単にこれらのメソッドを使って描画しただけでは)そのコントロールは無効状態に見えないのだ。

 次の画面は、実際にはフォーム上のすべてのコントロールが無効化されているにもかかわらず、そのようには見えない例である。

独自に描画を行ったために無効状態に見えないコントロールの例
フォームを無効化する(EnabledプロパティをFalseに設定する)ことで、フォーム上のすべてのコントロールを無効化したところ。だが、一部のコントロール()は無効化されているようには見えない。
  Panelコントロール上に、DrawStringメソッドを用いて「文字列描画」という文字列を描画している。Panelコントロールは無効化されているので、それが分かるように、と同じようなグレー・アウトした状態で文字列が表示されるべきだが、そうなっていない。
  PictureBoxコントロール上にImageプロパティに指定した画像がDrawImageメソッドによって描画されている(これはPictureBoxコントロールが持つ機能である)。しかしPictureBoxコントロールが無効化されたときには、画像をグレー・アウトした状態で表示すべきだが、そうならない。
  独自に描画を行っていないGroupBoxコントロール、TextBoxコントロール、Buttonコントロールは、EnabledプロパティをFalseに設定するだけで、この画面例のようなグレー・アウトした状態で表示される。

 この画面例を見ると分かるように、フォーム上のすべてのコントロールが無効化されているにもかかわらず、DrawStringメソッドやDrawImageメソッドを使って描画を行っているコントロール(この例では、PanelコントロールとPictureBoxコントロール)だけが、グレー・アウトした状態で表示されていない。そのため、コントロールを見ただけでは無効になっているかどうかを判別できない。これではやはりユーザビリティの面で問題となるだろう。

無効状態での文字列と画像の描画

 文字列や画像を無効状態で(つまりグレー色で)描画するためには、それぞれControlPaintクラス(System.Windows.Forms名前空間)の次のメソッドを使えばよい(いずれも静的メソッドなので、直接呼び出せる)。

 コントロールが無効化されている場合には、先ほどのDrawStringメソッドやDrawImageメソッドの代わりに、このDrawStringDisabledメソッドやDrawImageDisabledメソッドを用いればよいわけである。

 次のコードは、コントロールのEnabledプロパティがFalseの場合に、DrawStringDisabledメソッドやDrawImageDisabledメソッドを用いて文字列や画像を描画する例である。なお、コントロールへの文字列や画像の描画は、そのコントロールのPaintイベント・ハンドラで行うことができる。

private void panel1_Paint(object sender, PaintEventArgs e)
{
  StringFormat strformat = new StringFormat();
  if (this.panel1.Enabled == true)
  {
    SolidBrush brushText = new SolidBrush(ForeColor);
    // 通常の文字列を描画する
    e.Graphics.DrawString(
      "文字列描画",   // 描画する文字列
      this.Font,      // フォント
      brushText,      // 色(ブラシ)
      e.ClipRectangle,// 描画領域
      strformat);     // 文字列の書式
    brushText.Dispose();
  }
  else
  {
    // 無効化された文字列を描画する
    ControlPaint.DrawStringDisabled(
      e.Graphics,     // 描画オブジェクト
      "文字列描画",   // 描画する文字列
      this.Font,      // フォント
      this.BackColor, // 色
      e.ClipRectangle,// 描画領域
      strformat);     // 文字列の書式
  }
  strformat.Dispose();
}

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
  if ((this.pictureBox1.Image != null) &&
    (this.pictureBox1.Enabled == false))
  {
    // 無効化された画像を描画する
    ControlPaint.DrawImageDisabled(
      e.Graphics,            // 描画オブジェクト
      this.pictureBox1.Image,// 描画する画像
      0, 0,                  // 描画開始位置(x座標、y座標)
      this.BackColor);       // 背景色(※使われていない)
  }
}
無効状態の文字列や画像を描画するサンプル・コード(C#)
 
Private Sub panel1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles panel1.Paint
  Dim strformat As StringFormat =  New StringFormat()
  If Me.panel1.Enabled = True Then
    Dim brushText As SolidBrush =  New SolidBrush(ForeColor)
    ' 通常の文字列を描画する
    e.Graphics.DrawString( _
      "文字列描画", _
      Me.Font, _
      brushText, _
      RectangleF.op_Implicit(e.ClipRectangle), _
      strformat)
    brushText.Dispose()
  Else
    ' 無効化された文字列を描画する
    ControlPaint.DrawStringDisabled( _
      e.Graphics, _
      "文字列描画", _
      Me.Font, _
      Me.BackColor, _
      RectangleF.op_Implicit(e.ClipRectangle), _
      strformat)
  End If
  strformat.Dispose()
End Sub

Private Sub pictureBox1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles pictureBox1.Paint
  If Not (Me.pictureBox1.Image Is Nothing) _
  And (Me.pictureBox1.Enabled = False) Then
    ' 無効化された画像を描画する
    ControlPaint.DrawImageDisabled( _
      e.Graphics, _
      Me.pictureBox1.Image, _
      0, 0, _
      Me.BackColor)
  End If
End Sub
無効状態の文字列や画像を描画するサンプル・コード(VB.NET)
DrawStringメソッドやDrawStringDisabledメソッドのパラメータで使われているRectangleF.op_Implicitメソッドは、Rectangle構造体のオブジェクトをRectangleF構造体のオブジェクトに型変換するためのものだ。詳しくはMSDNの「Rectangle から RectangleF への変換」を参照してほしい。なお、C#のコードにはあるDrawStringDisabledメソッドやDrawImageDisabledメソッドのパラメータ内容についてのコメントは、このVB.NETのコードでは割愛している。これは、VB.NETのコード規約ではアンダーバーによる行継続とコメントを併記できないためである。従って、パラメータ内容はC#のコードを参照すること。

 このサンプル・コードの内容を冒頭のWindowsフォームのプログラムに追加して実行したものが、次の画面である。

独自に描画を行っても正しく無効状態に見えるコントロールの例
フォームを無効化する(EnabledプロパティをFalseに設定する)ことで、フォーム上のすべてのコントロールを無効化したところ。すべてのコントロールが無効化されているのが、見ただけですぐに分かる。
  Panelコントロール上に、無効化された状態の文字列が表示されている。
  PictureBoxコントロール上に、無効化された状態の画像が表示されている。

 なお、ControlPaint.DrawImageDisabledメソッドの第5パラメータにある背景色の指定は実際の描画色として適用されてないようだ(これは恐らく、.NET Frameworkのバグであろう)。このため、いくら背景色を変更しても、常にこの画面例と同じ色でしか描画されないので注意してほしい。End of Article

カテゴリ:クラス・ライブラリ 処理対象:ビットマップ
カテゴリ:Windowsフォーム 処理対象:ウィンドウ
カテゴリ:Windowsフォーム 処理対象:コントロール
使用ライブラリ:Graphicsクラス(System.Drawing名前空間)
使用ライブラリ:ControlPaintクラス(System.Windows.Forms名前空間)
関連TIPS:画像を高品質に拡大/縮小するには?
 
この記事と関連性の高い別の.NET TIPS
ダブル・バッファリングにより描画を行うには?(DoubleBuffered編)
ダブル・バッファリングにより描画を行うには?
PictureBoxコントロールにグラフィックを描画するには?
背景の描画を禁止して再描画時のちらつきをなくすには?
ウィンドウのリサイズ時に再描画を行うには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間