注意:ここで紹介している方法は、.NET Framework 2.0以降でのみ使用できます。
ToolStripコントロール(MenuStrip、ContextMenuStrip、StatusStripなどToolStripから派生したコントロールを含む)に配置できるアイテムには、色々なものが用意されています。例えばToolStripComboBoxクラスを使えばコンボボックスを、ToolStripTextBoxクラスを使えばテキストボックスを、ToolStripProgressBarクラスを使えばプログレスバーを配置することができます。しかし、それ以外のコントロールを配置するにはどのようにすればよいのでしょうか?
それを解決する方法がちゃんと用意されています。ToolStripControlHostクラスを使えば、任意のコントロールをToolStripにのせることができます。ここではToolStripControlHostを使用した例として、NumericUpDownコントロールをToolStripにのせる方法を説明します。
補足:ToolStripコントロールに配置できるアイテムは、ToolStripItemクラスから派生したもののみです。.NET Framework 2.0では、ToolStripItemクラスから派生したアイテムとして、以下のようなものが用意されています。
アイテム | 説明 |
---|---|
ToolStripButtonクラス | ツールバーの普通のボタン。画像とテキストが表示できる。主に、ToolStripで使用される。 |
ToolStripDropDownButtonクラス | 押すとドロップダウンリストが表示されるボタン。主に、ToolStrip、StatusStripで使用される。 |
ToolStripSplitButtonクラス | ToolStripDropDownButtonと見た目が似ているが、こちらは普通のボタンとドロップダウンボタンが並んでいる。主に、ToolStrip、StatusStripで使用される。 |
ToolStripLabelクラス | テキストや画像を表示できる。コメントやタイトル、あるいはハイパーリンクとして使用することもできる。主に、ToolStripで使用される。 |
ToolStripSeparatorクラス | グループ分けするセパレータ。主に、ToolStrip、MenuStrip、ContextMenuStripで使用される。 |
ToolStripMenuItemクラス | メニューで使われる項目。画像も表示可能。主に、MenuStrip、ContextMenuStripで使用される。 |
ToolStripStatusLabelクラス | ステータスバーで使われるパネル。テキストや画像を表示できる。主に、StatusStripで使用される。 |
ToolStripComboBoxクラス | コンボボックスを表示する。主に、ToolStrip、MenuStrip、ContextMenuStripで使用される。 |
ToolStripTextBoxクラス | テキストボックスを表示する。主に、ToolStrip、MenuStrip、ContextMenuStripで使用される。 |
ToolStripProgressBarクラス | ProgressBarを表示する。主に、ToolStrip、StatusStripで使用される。 |
まずは、最もお手軽な方法を紹介します。ToolStripControlHostクラスのコンストラクタのパラメータにNumericUpDownオブジェクトを指定して、インスタンスを作成します。これをToolStripに追加すれば、OKです。
以下に示すコードは、すでにフォームに配置されているToolStripコントロール(ToolStrip1)にNumericUpDownコントロールをのせる例です。このコードは、ToolStrip1のあるフォームクラスに書かれてるものとします。
Private toolStripNumeric1 As ToolStripControlHost 'フォームのLoadイベントハンドラ Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As EventArgs) _ Handles MyBase.Load 'ToolStripにのせるコントロール Dim ctrl As New NumericUpDown() 'NumericUpDownをホストするToolStripControlHostを作成する Me.toolStripNumeric1 = New ToolStripControlHost(ctrl) 'ToolStripに追加する ToolStrip1.Items.Add(toolStripNumeric1) End Sub
private ToolStripControlHost toolStripNumeric1; //フォームのLoadイベントハンドラ private void Form1_Load(object sender, System.EventArgs e) { //ToolStripにのせるコントロール NumericUpDown ctrl = new NumericUpDown(); //NumericUpDownをホストするToolStripControlHostを作成する this.toolStripNumeric1 = new ToolStripControlHost(ctrl); //ToolStripに追加する ToolStrip1.Items.Add(toolStripNumeric1); }
NumericUpDownコントロールをToolStripにのせることはできましたが、NumericUpDownコントロールにアクセスするにはどのようにすればよいのでしょうか?例えば、現在の値(Valueプロパティ)を取得するには、どうしたらいいのでしょうか?
ToolStripControlHostがホストしているコントロールは、Controlプロパティで取得できるため、次のようなコードで、Valueプロパティの値を取得できます。
'NumericUpDownにキャストする Dim ctrl As NumericUpDown = DirectCast(toolStripNumeric1.Control, NumericUpDown) 'NumericUpDownの値を取得する Dim val As Decimal = ctrl.Value
//NumericUpDownにキャストする NumericUpDown ctrl = (NumericUpDown)toolStripNumeric1.Control; //NumericUpDownの値を取得する decimal val = ctrl.Value;
次に、ToolStripControlHostの派生クラスを作成する方法を紹介します。このようにクラスを作成しておけば、ToolStripButtonなどと同様に、簡単にToolStripに追加できるようになります。
まず、次のようなクラスを作成します。あまりに簡単ですが、これだけで十分です。
Imports System.Windows.Forms Public Class ToolStripNumericUpDown Inherits ToolStripControlHost Public Sub New() MyBase.New(New NumericUpDown()) End Sub End Class
using System.Windows.Forms; public class ToolStripNumericUpDown : ToolStripControlHost { public ToolStripNumericUpDown() : base(new NumericUpDown()) { } }
これを実際にToolStripにのせる方法は、普通のToolStripItemをToolStripにのせる場合と同じです。コードで書くと、以下のようになります。
Private toolStripNumeric1 As ToolStripControlHost 'フォームのLoadイベントハンドラ Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As EventArgs) _ Handles MyBase.Load 'ToolStripNumericUpDownオブジェクトを作成する toolStripNumeric1 = New ToolStripNumericUpDown() 'ToolStripに追加する ToolStrip1.Items.Add(toolStripNumeric1) End Sub
private ToolStripControlHost toolStripNumeric1; //フォームのLoadイベントハンドラ private void Form1_Load(object sender, System.EventArgs e) { //ToolStripNumericUpDownオブジェクトを作成する toolStripNumeric1 = new ToolStripNumericUpDown(); //ToolStripに追加する ToolStrip1.Items.Add(toolStripNumeric1); }
このようなコードを自分で書かずに、Visual Studioのフォームデザイナを使ってToolStripNumericUpDownをToolStripに配置することもできます。この方法は、「自作したToolStripItemをVisual Studioのデザイナで表示する」で説明します。
ToolStripにのせたNumericUpDownコントロールにアクセスする方法は前に説明した方法と同じで、ToolStripControlHost.Controlプロパティを使います。
これだけでも十分かもしれませんが、ToolStripNumericUpDownクラスをもう少し改良すると、さらに使いやすくなります。
まず、ホストしているNumericUpDownコントロールをプロパティで公開します。また、よく使うメソッドやプロパティもToolStripNumericUpDownクラスで公開します。ここでは、NumericUpDownの値を設定、取得するためのValueプロパティを作成します。
さらに、ToolStripNumericUpDownクラス内でNumericUpDownのイベントを処理する必要があれば、OnSubscribeControlEventsとOnUnsubscribeControlEventsメソッドを使用すると、効率的です。ここでは、NumericUpDownの値が変化した時に発生するValueChangedイベントを追加することにします。
以上のように改良したToolStripNumericUpDownクラスは、次のようになります。
Imports System.Windows.Forms Public Class ToolStripNumericUpDown Inherits ToolStripControlHost ''' <summary> ''' コンストラクタ ''' </summary> Public Sub New() MyBase.New(New NumericUpDown()) End Sub ''' <summary> ''' ホストしているNumericUpDownコントロール ''' </summary> Public ReadOnly Property NumericUpDown() As NumericUpDown Get Return DirectCast(Control, NumericUpDown) End Get End Property ''' <summary> ''' 値の設定と取得 ''' </summary> Public Property Value() As Decimal Get Return NumericUpDown.Value End Get Set(ByVal value As Decimal) NumericUpDown.Value = value End Set End Property 'ホストしているNumericUpDownのイベントをサブスクライブする Protected Overrides Sub OnSubscribeControlEvents( _ ByVal control As Control) MyBase.OnSubscribeControlEvents(control) Dim numControl As NumericUpDown = _ DirectCast(control, NumericUpDown) AddHandler numControl.ValueChanged, _ AddressOf NumericUpDown_OnValueChanged End Sub 'ホストしているNumericUpDownのイベントをアンサブスクライブする Protected Overrides Sub OnUnsubscribeControlEvents( _ ByVal control As Control) MyBase.OnUnsubscribeControlEvents(control) Dim numControl As NumericUpDown = _ DirectCast(control, NumericUpDown) RemoveHandler numControl.ValueChanged, _ AddressOf NumericUpDown_OnValueChanged End Sub ''' <summary> ''' 値が変化した時に発生するイベント ''' </summary> Public Event ValueChanged As EventHandler 'ValueChangedイベントを発生 Private Sub NumericUpDown_OnValueChanged( _ ByVal sender As Object, ByVal e As EventArgs) RaiseEvent ValueChanged(Me, e) End Sub End Class
using System.Windows.Forms; public class ToolStripNumericUpDown : ToolStripControlHost { /// <summary> /// コンストラクタ /// </summary> public ToolStripNumericUpDown() : base(new NumericUpDown()) { } /// <summary> /// ホストしているNumericUpDownコントロール /// </summary> public NumericUpDown NumericUpDown { get { return (NumericUpDown)Control; } } /// <summary> /// 値の設定と取得 /// </summary> public decimal Value { get { return NumericUpDown.Value; } set { NumericUpDown.Value = value; } } //ホストしているNumericUpDownのイベントをサブスクライブする protected override void OnSubscribeControlEvents(Control control) { base.OnSubscribeControlEvents(control); NumericUpDown numControl = (NumericUpDown)control; numControl.ValueChanged += new EventHandler(NumericUpDown_OnValueChanged); } //ホストしているNumericUpDownのイベントをアンサブスクライブする protected override void OnUnsubscribeControlEvents(Control control) { base.OnUnsubscribeControlEvents(control); NumericUpDown numControl = (NumericUpDown)control; numControl.ValueChanged -= new EventHandler(NumericUpDown_OnValueChanged); } /// <summary> /// 値が変化した時に発生するイベント /// </summary> public event EventHandler ValueChanged; //ValueChangedイベントを発生 private void NumericUpDown_OnValueChanged(object sender, EventArgs e) { if (ValueChanged != null) { ValueChanged(this, e); } } }
改良したToolStripNumericUpDownクラスの使い方は、次のようになります。
Private toolStripNumeric1 As ToolStripNumericUpDown Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As EventArgs) _ Handles MyBase.Load 'ToolStripNumericUpDownの作成 toolStripNumeric1 = New ToolStripNumericUpDown() 'toolStripNumeric1の値を変更 toolStripNumeric1.Value = 5 'ValueChangedイベントハンドラの追加 AddHandler toolStripNumeric1.ValueChanged, _ AddressOf toolStripNumeric1_ValueChanged 'ToolStrip1に追加 ToolStrip1.Items.Add(toolStripNumeric1) End Sub Sub toolStripNumeric1_ValueChanged( _ ByVal sender As Object, ByVal e As EventArgs) Console.WriteLine("値が変わったよ") End Sub
private ToolStripNumericUpDown toolStripNumeric1; //フォームのLoadイベントハンドラ private void Form1_Load(object sender, System.EventArgs e) { //ToolStripNumericUpDownの作成 toolStripNumeric1 = new ToolStripNumericUpDown(); //toolStripNumeric1の値を変更 toolStripNumeric1.Value = 5; //ValueChangedイベントハンドラの追加 toolStripNumeric1.ValueChanged += new EventHandler(toolStripNumeric1_ValueChanged); //ToolStrip1に追加 ToolStrip1.Items.Add(toolStripNumeric1); } void toolStripNumeric1_ValueChanged(object sender, EventArgs e) { Console.WriteLine("値が変わったよ"); }
(この記事は、「.NETプログラミング研究」で紹介したものを基にしています。)