.NET TIPS

独自にサイズ・グリップを描画するには?[2.0、3.0、3.5、C#、VB]

デジタルアドバンテージ 一色 政彦
2010/02/18

 「TIPS:フォーム全体へのドッキング状態でサイズ変更つまみを表示するには?」では、Windowsフォームがサイズ変更可能であることを明示する右下のつまみ(以降、サイズ・グリップ)を表示する方法を紹介した。

 サイズ・グリップはWindowsフォームが持つ標準機能だが、フォーム全体にコントロールがドッキングしているような場合、右下のサイズ・グリップが隠れてしまう。このような事態に対処するには、前掲のTIPSで紹介したようにStatusStripコントロールを利用する方法もあるが、このほかにフォーム上に被さっているコントロール内にサイズ・グリップを独自に描画する方法もある。本TIPSではこの方法を紹介する。

●独自にサイズ・グリップを描画する方法

 独自にサイズ・グリップを描画するには、コントロールの描画時に発生するPaintイベントで、VisualStyleRendererクラス(System.Windows.Forms.VisualStyles名前空間)のインスタンス・メソッドであるDrawBackgroundメソッドを呼び出せばよい。その構文は下記のようになっている。

DrawBackgroundメソッド

  • 第1パラメータ(IDeviceContext):描画に使用するIDeviceContextインターフェイス(System.Drawing名前空間)を実装したクラスのオブジェクト。通常は、Graphicsクラス(System.Drawing名前空間)のオブジェクトを指定する。
  • 第2パラメータ(Rectangle):描画対象の領域(左上隅のx座標、y座標、幅、高さ)。
  • 戻り値(void):なし。

 VisualStyleRendererクラスをインスタンス化するには、下記の構文を持つコンストラクタを利用する。

VisualStyleRendererコンストラクタ

 今回の場合はサイズ・グリップであるため、この第1パラメータには「VisualStyleElement.Status.Gripper.Normal」プロパティの値を常に指定する。このプロパティから取得できる値は、VisualStyleElementクラス(System.Windows.Forms.VisualStyles名前空間)のオブジェクトである。なお、VisualStyleElement.Status.Gripperクラスも、System.Windows.Forms.VisualStyles名前空間に所属するクラスである。

 サイズ・グリップの描画には、基本的に上記のDrawBackgroundメソッドを利用すればよいが、ビジュアル・スタイルはWindows XP以降で導入されている機能であるため、OSがビジュアル・スタイルやサイズ・グリップ要素に対応していない場合にはInvalidOperationException例外やArgumentException例外が発生してしまう。これを回避するには、ビジュアル・スタイル要素の対応状況をチェックする必要がある。これを行うのが、次の静的プロパティと静的メソッドだ(下記のApplicationクラスはSystem.Windows.Forms名前空間に所属)。

機能:OSがビジュアル・スタイル機能に対応しており、現在のアプリケーションがビジュアル・スタイル機能を有効にしているか?
VisualStyleRenderer.IsSupportedプロパティ(static/Shared)

  • 取得(Boolean):true=対応。false=非対応。

機能:指定されたビジュアル・スタイル要素がサポートされているか?
VisualStyleRenderer.IsElementDefinedメソッド(static/Shared)

  • 第1パラメータ(VisualStyleElement):描画に使用するビジュアル・スタイル要素。
  • 戻り値(Boolean):true=対応。false=非対応。

 VisualStyleRenderer.IsElementDefinedメソッドの第1パラメータには、先ほどのVisualStyleRendererコンストラクタと同様に「VisualStyleElement.Status.Gripper.Normal」を指定すればよい。

 これらの静的プロパティと静的メソッドがすべてtrueの場合は、上記のDrawBackgroundメソッドを利用できる。

 それ以外の場合は、ControlPaintクラスの静的メソッドであるDrawSizeGripメソッドを呼び出せばよい。このメソッドはビジュアル・スタイルではないサイズ・グリップを描画するためのメソッドだ。その構文は下記のようになっている。

DrawSizeGripメソッド(static/Shared)

  • 第1パラメータ(Graphics):描画に使用するGraphicsオブジェクト。
  • 第2パラメータ(Color):サイズ・グリップの背景色として使用されるColorクラス(System.Drawing名前空間)のオブジェクト。
  • 第3パラメータ(Rectangle):サイズ・グリップの領域(左上隅のx座標、y座標、幅、高さ)。
  • 戻り値(void):なし。

 以上の内容をすべて含む、Windowsフォームでの実装例を示す。例えばPanelコントロールの右下に16×16のサイズ・グリップを描画するコードは、下記のようになる。なおPaintイベント・ハンドラは、(Panelコントロールの派生クラスではなく)Windowsフォーム側で処理している。

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

private const int SIZEGRIP_SIZE = 16;
private VisualStyleRenderer _sizeGripRenderer = null;

private void panel1_Paint(object sender, PaintEventArgs e)
{
  Size sz = this.panel1.ClientSize;
  Rectangle rect = new Rectangle(
              sz.Width - SIZEGRIP_SIZE,
              sz.Height - SIZEGRIP_SIZE,
              SIZEGRIP_SIZE,
              SIZEGRIP_SIZE);

  if ((Application.RenderWithVisualStyles) &&
      (VisualStyleRenderer.IsElementDefined(
        VisualStyleElement.Status.Gripper.Normal)))
  {
      if (_sizeGripRenderer == null)
      {
        _sizeGripRenderer =  new VisualStyleRenderer(
          VisualStyleElement.Status.Gripper.Normal);
      }

    // 右下の16×16の領域にサイズ・グリップを描画する(新式)
    _sizeGripRenderer.DrawBackground(e.Graphics, rect);
  }
  else
  {
    // 右下の16×16の領域にサイズ・グリップを描画する(旧式)
    ControlPaint.DrawSizeGrip(e.Graphics, this.BackColor, rect);
  }
}

private void panel1_Resize(object sender, EventArgs e)
{
  panel1.Invalidate();
}
Imports System.Windows.Forms.VisualStyles

Private Const SIZEGRIP_SIZE As Integer = 16
Private _sizeGripRenderer As VisualStyleRenderer = Nothing

Private Sub panel1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles panel1.Paint

  Dim sz As Size = Me.panel1.ClientSize
  Dim rect As New Rectangle( _
        sz.Width - SIZEGRIP_SIZE, _
        sz.Height - SIZEGRIP_SIZE, _
        SIZEGRIP_SIZE, _
        SIZEGRIP_SIZE)

  If (Application.RenderWithVisualStyles) AndAlso _
      (VisualStyleRenderer.IsElementDefined( _
      VisualStyleElement.Status.Gripper.Normal)) Then

    If _sizeGripRenderer Is Nothing Then
      _sizeGripRenderer = New VisualStyleRenderer( _
        VisualStyleElement.Status.Gripper.Normal)
    End If

    ' 右下の16×16の領域にサイズ・グリップを描画する(新式)
    _sizeGripRenderer.DrawBackground(e.Graphics, rect)
  Else
    ' 右下の16×16の領域にサイズ・グリップを描画する(旧式)
    ControlPaint.DrawSizeGrip(e.Graphics, Me.BackColor, rect)
  End If

End Sub

Private Sub panel1_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles panel1.Resize
  Me.panel1.Invalidate()
End Sub
Windowsフォームで独自にサイズ・グリップを描画するコード(上:C#、下:VB)

 上記のコードで注意してほしいのが、PanelコントロールのResizeイベント・ハンドラで、PanelコントロールのInvalidateメソッドを呼び出し、コントロールの再描画を行っている点だ。これを行わない場合、Windowsフォームをリサイズしたときに、以前の描画が残存してしまう。詳しくは「TIPS:ウィンドウのリサイズ時に再描画を行うには?」を参照してほしい。End of Article

利用可能バージョン:.NET Framework 2.0
利用可能バージョン:.NET Framework 3.0
利用可能バージョン:.NET Framework 3.5
カテゴリ:Windowsフォーム 処理対象:独自描画コントロール
使用ライブラリ:VisualStyleRendererクラス(System.Windows.Forms.VisualStyles名前空間)
使用ライブラリ:VisualStyleElementクラス(System.Windows.Forms.VisualStyles名前空間)
使用ライブラリ:IDeviceContextクラス(System.Drawing名前空間)
使用ライブラリ:Graphicsクラス(System.Drawing名前空間)
使用ライブラリ:Colorクラス(System.Drawing名前空間)
使用ライブラリ:Applicationクラス(System.Windows.Forms名前空間)
関連TIPS:フォーム全体へのドッキング状態でサイズ変更つまみを表示するには?
関連TIPS:ウィンドウのリサイズ時に再描画を行うには?
関連TIPS:WindowsアプリケーションをWindows XPスタイルの外観にするには?

この記事と関連性の高い別の.NET TIPS
フォーム全体へのドッキング状態でサイズ変更つまみを表示するには?
文字列や画像を無効状態で描画するには?
ウィンドウのリサイズ時に再描画を行うには?
ダブル・バッファリングにより描画を行うには?(DoubleBuffered編)
ダブル・バッファリングにより描画を行うには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム 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 記事ランキング

本日 月間