.NET Framework 2.0から追加されたStatusStripでは、「ToolStrip(ツールバー、メニュー、ステータスバー)に任意のコントロールを配置する」で紹介している方法により可能です。
ステータスバーにコントロールを追加するには、ステータスバーの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」も参考にしています。
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
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イベントハンドラや、コンストラクタなどに記述してください。
'パネルを表示する StatusBar1.ShowPanels = True 'StatusBar1のパネルにProgressBar1を追加する Dim csbp As New ControlStatusBarPanel(ProgressBar1, StatusBar1) StatusBar1.Panels.Add(csbp)
//パネルを表示する StatusBar1.ShowPanels = true; //StatusBar1のパネルにProgressBar1を追加する ControlStatusBarPanel csbp = new ControlStatusBarPanel(ProgressBar1, StatusBar1); StatusBar1.Panels.Add(csbp);