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

MDI親フォームの背景を描画する

MDI親フォームの背景に画像を表示するには、フォームのBackGroundプロパティが使えます。「MDI親フォームの背景色を変更する」で紹介したBackColorプロパティとは違い、BackGroundプロパティに指定された画像はクライアント領域に正常に表示されます(画像はタイル状に表示されます)。

MDI親フォームの背景を独自に描画する方法は、「vbAccelerator - Painting in the MDI Client Area」で紹介されています。vbAcceleratorで紹介されている方法は、Win32 APIを使う方法で、かなり複雑です。

このように難しい方法を使わなくても、「MDI親フォームの背景色を変更する」で紹介したMdiClientコントロールのPaintイベントを使ってMDI親フォームのクライアント領域を描画すれば、もっと簡単に実現できます。

注意:ただし、.NET Framework 1.1以前のヘルプによると、MdiClientクラスは「独自に作成したコード内で直接使用することはできません。」とありますので、この方法が適切であるかは保障できません。.NET Framework 2.0からは、このような文言はなくなりました。

以下に紹介するサンプルでは、MDI親フォームのクライアント領域に画像("back.bmp")をクライアント領域の大きさに合わせて描画するようにしています。なお、このコードはMDI親フォームに記述されており、ParentForm_LoadはフォームのLoadイベントハンドラとして登録されているものとします。

VB.NET
コードを隠すコードを選択
'背景に表示する画像
Dim back As New Bitmap("back.bmp")

'MDI親フォームのLoadイベントハンドラ
Private Sub ParentForm_Load(sender As Object, _
    e As System.EventArgs) Handles MyBase.Load
    Me.IsMdiContainer = True
    'MdiClientの取得
    Dim mc As System.Windows.Forms.MdiClient = GetMdiClient(Me)
    'MdiClientのPaintとResizeイベントハンドラを追加
    AddHandler mc.Paint, AddressOf MdiClient_Paint
    AddHandler mc.Resize, AddressOf MdiClient_Resize
End Sub

Private Sub MdiClient_Paint(sender As Object, e As PaintEventArgs)
    Dim mc As System.Windows.Forms.MdiClient = _
        CType(sender, System.Windows.Forms.MdiClient)
    '画像をクライアント領域にあわせて描画する
    e.Graphics.DrawImage(back, mc.ClientRectangle)
End Sub

Private Sub MdiClient_Resize(sender As Object, e As EventArgs)
    Dim mc As System.Windows.Forms.MdiClient = _
        CType(sender, System.Windows.Forms.MdiClient)
    'Paintイベントを呼び出す
    mc.Invalidate()
End Sub

''' <summary>
''' フォームのMdiClientコントロールを探して返す
''' </summary>
''' <param name="f">MdiClientコントロールを探すフォーム</param>
''' <returns>見つかったMdiClientコントロール</returns>
Public Shared Function GetMdiClient( _
    ByVal f As System.Windows.Forms.Form) _
    As System.Windows.Forms.MdiClient
    Dim c As System.Windows.Forms.Control
    For Each c In f.Controls
        If TypeOf c Is System.Windows.Forms.MdiClient Then
            Return CType(c, System.Windows.Forms.MdiClient)
        End If
    Next c
    Return Nothing
End Function
C#
コードを隠すコードを選択
//背景に表示する画像
Bitmap back = new Bitmap("back.bmp");

//MDI親フォームのLoadイベントハンドラ
private void ParentForm_Load(object sender, System.EventArgs e)
{
    this.IsMdiContainer = true;
    //MdiClientの取得
    System.Windows.Forms.MdiClient mc = GetMdiClient(this);
    //MdiClientのPaintとResizeイベントハンドラを追加
    mc.Paint += new PaintEventHandler(MdiClient_Paint);
    mc.Resize += new EventHandler(MdiClient_Resize);
}

private void MdiClient_Paint(object sender, PaintEventArgs e)
{
    System.Windows.Forms.MdiClient mc =
        (System.Windows.Forms.MdiClient) sender;
    //画像をクライアント領域にあわせて描画する
    e.Graphics.DrawImage(back, mc.ClientRectangle);
}

private void MdiClient_Resize(object sender, EventArgs e)
{
    System.Windows.Forms.MdiClient mc =
        (System.Windows.Forms.MdiClient) sender;
    //Paintイベントを呼び出す
    mc.Invalidate();
}

/// <summary>
/// フォームのMdiClientコントロールを探して返す
/// </summary>
/// <param name="f">MdiClientコントロールを探すフォーム</param>
/// <returns>見つかったMdiClientコントロール</returns>
public static System.Windows.Forms.MdiClient 
    GetMdiClient(System.Windows.Forms.Form f)
{
    foreach (System.Windows.Forms.Control c in f.Controls)
        if (c is System.Windows.Forms.MdiClient)
            return (System.Windows.Forms.MdiClient) c;
    return null;
}

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。