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

ステータスバーにコントロールを追加する

StatusStripコントロールの場合

.NET Framework 2.0から追加されたStatusStripでは、「ToolStrip(ツールバー、メニュー、ステータスバー)に任意のコントロールを配置する」で紹介している方法により可能です。

StatusBarコントロールの場合

ステータスバーにコントロールを追加するには、ステータスバーのControlsプロパティのAddメソッドを使用すれば(または、コントロールのParentプロパティにステータスバーを指定すれば)よい訳ですが、コントロールの位置と大きさをどう調節すればいいのかという問題が残ります。できればStatusBarに追加されているPanelの上に乗るように調節したいところですが、Panelの位置と大きさを知る方法と、Panelの位置と大きさが変更されたことを知る方法が一見なさそうで、これらをどうやって克服するかが問題となります。

Panelの位置と大きさを知る方法は、「The Code Project - A class to put a ProgressBar or any control into a StatusBar」で紹介されています。この記事によると、SendMessage関数を使用して、

SendMessage(StatusBar.Handle.ToInt32, SB_GETRECT, Panel, Rectangle)

のようにするとのことです。しかしこのサンプルではフォームのResizeイベントでPanelの大きさが変更されたか判断しているようですが、これでは十分ではないでしょう。

「GotDotNet Message Boards - Re: Progress Bar in the Status Bar」(リンク切れ)では別の解決法が紹介されています。それは、StatusBarのDrawItemイベントハンドラを使用する方法です。ここでは、この方法に従ってサンプルコードを書くことにします。

下のコードでは、StatusBarPanelクラスの派生クラスを作成し、これをStatusBarのPanelに追加するだけでコントロールが表示されるようにしています。なおこのクラスの作成には、「Edneeis - Control - MDI Progressbar StatusBar Panel」も参考にしています。

VB.NET
コードを隠すコードを選択
Imports System
Imports System.Drawing
Imports System.Windows.Forms

''' <summary>
''' StatusBarのPanelにコントロールを乗せるクラス
''' </summary>
Public Class ControlStatusBarPanel
    Inherits StatusBarPanel

    Private _control As Control = Nothing
    ''' <summary>
    ''' Panelにのっているコントロール
    ''' </summary>
    Public ReadOnly Property Control() As Control
        Get
            Return _control
        End Get
    End Property

    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <param name="ctr">表示するコントロール</param>
    ''' <param name="sb">コントロールを乗せるStatusBar</param>
    Public Sub New(ByVal ctr As Control, ByVal sb As StatusBar)
        'OwnerDrawにする
        Me.Style = StatusBarPanelStyle.OwnerDraw
        '境界線をなくす
        Me.BorderStyle = StatusBarPanelBorderStyle.None

        _control = ctr
        'StatusBarにコントロールを追加する
        sb.Controls.Add(ctr)
        'StatusBarDrawItemEventHandlerイベントハンドラを追加
        AddHandler sb.DrawItem, AddressOf sb_DrawItem
    End Sub

    Private Sub sb_DrawItem(ByVal sender As Object, _
            ByVal sbdevent As StatusBarDrawItemEventArgs)
        'このPanelを描画しようとしているとき、
        'コントロールの大きさと位置を変更する
        If sbdevent.Panel.Equals(Me) Then
            _control.Bounds = sbdevent.Bounds
        End If
    End Sub
End Class
C#
コードを隠すコードを選択
using System;
using System.Drawing;
using System.Windows.Forms;

/// <summary>
/// StatusBarのPanelにコントロールを乗せるクラス
/// </summary>
public class ControlStatusBarPanel : StatusBarPanel
{
    private Control _control = null;
    /// <summary>
    /// Panelにのっているコントロール
    /// </summary>
    public Control Control
    {
        get
        {
            return _control;
        }
    }

    /// <summary>
    /// コンストラクタ
    /// </summary>
    /// <param name="ctr">表示するコントロール</param>
    /// <param name="sb">コントロールを乗せるStatusBar</param>
    public ControlStatusBarPanel(Control ctr, StatusBar sb)
    {
        //OwnerDrawにする
        this.Style = StatusBarPanelStyle.OwnerDraw;
        //境界線をなくす
        this.BorderStyle = StatusBarPanelBorderStyle.None;

        _control = ctr;
        //StatusBarにコントロールを追加する
        sb.Controls.Add(ctr);
        //StatusBarDrawItemEventHandlerイベントハンドラを追加
        sb.DrawItem += 
            new StatusBarDrawItemEventHandler(sb_DrawItem);
    }

    private void sb_DrawItem(object sender,
        StatusBarDrawItemEventArgs sbdevent)
    {
        //このPanelを描画しようとしているとき、
        //コントロールの大きさと位置を変更する
        if (sbdevent.Panel == this)
        {
            _control.Bounds = sbdevent.Bounds;
        }
    }
}

このクラスの使い方は、次のようになります(フォームにステータスバーStatusBar1とプログレスバーProgressBar1があり、ProgressBar1をStatusBar1に追加しています)。フォームのLoadイベントハンドラや、コンストラクタなどに記述してください。

VB.NET
コードを隠すコードを選択
'パネルを表示する
StatusBar1.ShowPanels = True

'StatusBar1のパネルにProgressBar1を追加する
Dim csbp As New ControlStatusBarPanel(ProgressBar1, StatusBar1)
StatusBar1.Panels.Add(csbp)
C#
コードを隠すコードを選択
//パネルを表示する
StatusBar1.ShowPanels = true;

//StatusBar1のパネルにProgressBar1を追加する
ControlStatusBarPanel csbp =
    new ControlStatusBarPanel(ProgressBar1, StatusBar1);
StatusBar1.Panels.Add(csbp);

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

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