.NETプログラミング研究 第68号 †
.NET Tips †
今回も前回に引き続き、ToolStripに関するTipsを紹介します。.NET Framework 2.0の新機能ですので、残念ながら1.0、1.1では使用できません。
ToolStripに任意のコントロールを配置する †
ToolStrip(MenuStrip、ContextMenuStrip、StatusStripなどToolStripから派生したコントロールを含む)に配置できるコントロールは、ToolStripItemクラスから派生したコントロールのみです。.NET Framework 2.0では、ToolStripItemクラスから派生したコントロールとして、以下のようなものが用意されています。
コントロール | 説明 |
ToolStripButton | ツールバーの普通のボタン。画像とテキストが表示できる。主に、ToolStripで使用される。 |
ToolStripDropDownButton | 押すとドロップダウンリストが表示されるボタン。Exploreで言えば、「表示」ボタンのような感じ。主に、ToolStrip、StatusStripで使用される。 |
ToolStripSplitButton | ToolStripDropDownButtonと似ているが、こちらはボタンとドロップダウンボタンが分かれている。Exploreで言えば、「戻る」や「進む」ボタンのような感じ。主に、ToolStrip、StatusStripで使用される。 |
ToolStripLabel | テキストや画像を表示する。コメントやタイトルとして使う。主に、ToolStrip、StatusStripで使用される。 |
ToolStripSeparator | グループ分けするセパレータ。主に、ToolStrip、MenuStrip、ContextMenuStripで使用される。 |
ToolStripMenuItem | メニューで使われる項目。画像も表示可能。主に、MenuStrip、ContextMenuStripで使用される。 |
ToolStripStatusLabel | StatusStripで使われるパネル。テキストや画像を表示できる。主に、ToolStripで使用される。 |
ToolStripComboBox | コンボボックスを表示する。主に、ToolStrip、MenuStrip、ContextMenuStripで使用される。 |
ToolStripTextBox | テキストボックスを表示する。主に、ToolStrip、MenuStrip、ContextMenuStripで使用される。 |
ToolStripProgressBar | ProgressBarを表示する。主に、ToolStrip、StatusStripで使用される。 |
注意:「主に...で使用される。」というのは、そのToolStripItemをVisual Studioのデザイナを使って配置することができるToolStripの種類を示しています。デザイナを使わずに、コードでToolStripに追加する場合は、その限りではありません。
このように、以前のToolBarとは違い、ToolStripには多くのコントロールをのせることができます。
これだけでも十分かもしれませんが、さらに、任意のコントロールをToolStripにのせるための方法が用意されています。それが、ToolStripControlHostクラスです。ここではToolStripControlHostを使用した例として、NumericUpDownコントロールをToolStripにのせる方法を説明します。
まず、次のようなクラスを作成します。あまりに簡単ですが、これだけで十分です。
1
2
3
4
5
6
7
| | Public Class ToolStripNumericUpDown
Inherits ToolStripControlHost
Public Sub New()
MyBase.New(New NumericUpDown())
End Sub
End Class
|
1
2
3
4
5
6
7
8
| | using System.Windows.Forms;
public class ToolStripNumericUpDown : ToolStripControlHost
{
public ToolStripNumericUpDown() : base(new NumericUpDown())
{
}
}
|
これを実際にToolStripにのせるには、次のようにします(フォームクラスに書かれてるものとします)。普通のToolStripItemをToolStripにのせる場合と同じです。
1
2
3
4
5
6
7
8
| | Private toolStripNumeric1 As ToolStripNumericUpDown
Protected Overrides Sub OnLoad(ByVal e As EventArgs)
MyBase.OnLoad(e)
toolStripNumeric1 = New ToolStripNumericUpDown()
ToolStrip1.Items.Add(toolStripNumeric1)
End Sub
|
1
2
3
4
5
6
7
8
9
| | private ToolStripNumericUpDown toolStripNumeric1;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
toolStripNumeric1 = new ToolStripNumericUpDown();
toolStrip1.Items.Add(toolStripNumeric1);
}
|
NumericUpDownコントロールをToolStripにのせることはできましたが、NumericUpDownコントロールにアクセスするにはどのようにすればよいのでしょうか?例えば、現在の値(Valueプロパティ)を取得するには、どうしたらいいのでしょうか?
ToolStripControlHostがホストしているコントロールは、Controlプロパティで取得できるため、次のようなコードで、Valueプロパティの値を取得できます。
1
| | Console.WriteLine(CType(toolStripNumeric1.Control, NumericUpDown).Value)
|
1
| | Console.WriteLine(((NumericUpDown)toolStripNumeric1.Control).Value);
|
このように、たったこれだけのコードでも十分ですが、ToolStripNumericUpDownクラスをもう少し改良すると、さらに使いやすくなります。
まず、ホストしているNumericUpDownをプロパティで公開します。また、よく使うメソッドやプロパティもToolStripNumericUpDownクラスで公開します。ここでは、NumericUpDownの値を設定、取得するためのValueプロパティを作成します。
さらに、ToolStripNumericUpDownクラス内でNumericUpDownのイベントを処理する必要があれば、OnSubscribeControlEventsとOnUnsubscribeControlEventsメソッドを使用すると、効率的です。ここでは、NumericUpDownの値が変化した時に発生するValueChangedイベントを追加することにします。
以上のように改良したToolStripNumericUpDownクラスは、次のようになります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
| | Public Class ToolStripNumericUpDown
Inherits ToolStripControlHost
Public Sub New()
MyBase.New(New NumericUpDown())
End Sub
Public ReadOnly Property NumericUpDown() As NumericUpDown
Get
Return CType(Control, NumericUpDown)
End Get
End Property
Public Property Value() As Decimal
Get
Return NumericUpDown.Value
End Get
Set(ByVal value As Decimal)
NumericUpDown.Value = value
End Set
End Property
Protected Overrides Sub OnSubscribeControlEvents( _
ByVal control As Control)
MyBase.OnSubscribeControlEvents(control)
Dim numControl As NumericUpDown = _
CType(control, NumericUpDown)
AddHandler numControl.ValueChanged, _
AddressOf NumericUpDown_OnValueChanged
End Sub
Protected Overrides Sub OnUnsubscribeControlEvents( _
ByVal control As Control)
MyBase.OnUnsubscribeControlEvents(control)
Dim numControl As NumericUpDown = _
CType(control, NumericUpDown)
RemoveHandler numControl.ValueChanged, _
AddressOf NumericUpDown_OnValueChanged
End Sub
Public Event ValueChanged As EventHandler
Private Sub NumericUpDown_OnValueChanged( _
ByVal sender As Object, ByVal e As EventArgs)
RaiseEvent ValueChanged(Me, e)
End Sub
End Class
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
| | using System.Windows.Forms;
public class ToolStripNumericUpDown : ToolStripControlHost
{
public ToolStripNumericUpDown() : base(new NumericUpDown())
{
}
public NumericUpDown NumericUpDown
{
get
{
return (NumericUpDown)Control;
}
}
public decimal Value
{
get
{
return NumericUpDown.Value;
}
set
{
NumericUpDown.Value = value;
}
}
protected override void OnSubscribeControlEvents(Control control)
{
base.OnSubscribeControlEvents(control);
NumericUpDown numControl = (NumericUpDown)control;
numControl.ValueChanged +=
new EventHandler(NumericUpDown_OnValueChanged);
}
protected override void OnUnsubscribeControlEvents(Control control)
{
base.OnUnsubscribeControlEvents(control);
NumericUpDown numControl = (NumericUpDown)control;
numControl.ValueChanged -=
new EventHandler(NumericUpDown_OnValueChanged);
}
public event EventHandler ValueChanged;
private void NumericUpDown_OnValueChanged(object sender, EventArgs e)
{
if (ValueChanged != null)
{
ValueChanged(this, e);
}
}
}
|
改良したToolStripNumericUpDownクラスの使い方は、次のようになります(フォームクラスに書かれてるものとします)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| | Private toolStripNumeric1 As ToolStripNumericUpDown
Protected Overrides Sub OnLoad(ByVal e As EventArgs)
MyBase.OnLoad(e)
toolStripNumeric1 = New ToolStripNumericUpDown()
toolStripNumeric1.Value = 5
AddHandler toolStripNumeric1.ValueChanged, _
AddressOf toolStripNumeric1_ValueChanged
ToolStrip1.Items.Add(toolStripNumeric1)
End Sub
Sub toolStripNumeric1_ValueChanged( _
ByVal sender As Object, ByVal e As EventArgs)
Console.WriteLine("値が変わったよ")
End Sub
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| | private ToolStripNumericUpDown toolStripNumeric1;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
toolStripNumeric1 = new ToolStripNumericUpDown();
toolStripNumeric1.Value = 5;
toolStripNumeric1.ValueChanged +=
new EventHandler(toolStripNumeric1_ValueChanged);
toolStrip1.Items.Add(toolStripNumeric1);
}
void toolStripNumeric1_ValueChanged(object sender, EventArgs e)
{
Console.WriteLine("値が変わったよ");
}
|
参考:
自作したToolStripItemをVisual Studioのデザイナで表示する †
Visual Studioのデザイナでは、ToolStripの端に新しいToolStripItemを追加するためのボタンが表示され、これを使って簡単にToolStripItemを追加することができます。しかし、「ToolStripに任意のコントロールをのせる」で紹介したような自作のToolStripItemの場合はVisual Studioのデザイナに表示されないため、コードでToolStripに配置しなければなりません。ここでは、自作ToolStripItemをVisual Studioのデザイナで表示させる方法を紹介します。
自作のToolStripItemをデザイナで表示してToolStripに追加できるようにするには、ToolStripItemDesignerAvailability属性を使用します。例えば、次のようなToolStripNumericUpDownを定義すれば、フォームデザイナのToolStripとStatusStripでこのToolStripNumericUpDownを追加することができるようになります。
1
2
3
4
5
6
7
8
9
10
| | <System.Windows.Forms.Design.ToolStripItemDesignerAvailability( _
System.Windows.Forms.Design.ToolStripItemDesignerAvailability.ToolStrip _
Or System.Windows.Forms.Design.ToolStripItemDesignerAvailability.StatusStrip)> _
Public Class ToolStripNumericUpDown
Inherits ToolStripControlHost
Public Sub New()
MyBase.New(New NumericUpDown())
End Sub
End Class
|
1
2
3
4
5
6
7
8
9
10
| | [System.Windows.Forms.Design.ToolStripItemDesignerAvailability(
System.Windows.Forms.Design.ToolStripItemDesignerAvailability.ToolStrip |
System.Windows.Forms.Design.ToolStripItemDesignerAvailability.StatusStrip)]
public class ToolStripNumericUpDown : ToolStripControlHost
{
public ToolStripNumericUpDown()
: base(new NumericUpDown())
{
}
}
|
さらに、デザイナでToolStripItemを追加する時のメニューで左側に表示される画像を変更するには、ToolboxBitmap属性を使います。(画像が指定されていないと、歯車の画像が表示されます。)
次の例では、「OpenFolder.bmp」という画像が「埋め込まれたリソース」としてアセンブリに埋め込まれている時に、これをToolStripNumericUpDownの画像としています。なお画像は、16X16の大きさである必要があります。
1
2
3
4
5
6
7
8
9
10
11
| | <System.Windows.Forms.Design.ToolStripItemDesignerAvailability( _
System.Windows.Forms.Design.ToolStripItemDesignerAvailability.ToolStrip _
Or System.Windows.Forms.Design.ToolStripItemDesignerAvailability.StatusStrip), _
ToolboxBitmap(GetType(ToolStripNumericUpDown), "OpenFolder.bmp")> _
Public Class ToolStripNumericUpDown
Inherits ToolStripControlHost
Public Sub New()
MyBase.New(New NumericUpDown())
End Sub
End Class
|
1
2
3
4
5
6
7
8
9
10
11
| | [System.Windows.Forms.Design.ToolStripItemDesignerAvailability(
System.Windows.Forms.Design.ToolStripItemDesignerAvailability.ToolStrip |
System.Windows.Forms.Design.ToolStripItemDesignerAvailability.StatusStrip)]
[ToolboxBitmap(typeof(ToolStripNumericUpDown), "OpenFolder.bmp")]
public class ToolStripNumericUpDown : ToolStripControlHost
{
public ToolStripNumericUpDown()
: base(new NumericUpDown())
{
}
}
|
これとは別に、ToolboxItem属性を使って画像を指定することもできます。この方法では、画像のほかに、表示名や説明を変更することもできます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| | <System.ComponentModel.ToolboxItem(GetType(NumericUpDownToolboxItem)), _
System.Windows.Forms.Design.ToolStripItemDesignerAvailability( _
System.Windows.Forms.Design.ToolStripItemDesignerAvailability.All)> _
Public Class ToolStripNumericUpDown
Inherits ToolStripControlHost
Public Sub New()
MyBase.New(New NumericUpDown())
End Sub
End Class
Public Class NumericUpDownToolboxItem
Inherits System.Drawing.Design.ToolboxItem
Public Sub New()
End Sub
Public Overrides Sub Initialize(ByVal type As Type)
MyBase.Initialize(type)
Me.Description = "数字を入力できます。"
Me.DisplayName = "数字入力"
Me.Bitmap = New Bitmap(GetType(NumericUpDownToolboxItem), _
"OpenFolder.bmp")
End Sub
End Class
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| | [System.ComponentModel.ToolboxItem(typeof(NumericUpDownToolboxItem))]
[System.Windows.Forms.Design.ToolStripItemDesignerAvailability(
System.Windows.Forms.Design.ToolStripItemDesignerAvailability.All)]
public class ToolStripNumericUpDown : ToolStripControlHost
{
public ToolStripNumericUpDown()
: base(new NumericUpDown())
{
}
}
public class NumericUpDownToolboxItem :
System.Drawing.Design.ToolboxItem
{
public NumericUpDownToolboxItem()
{
}
public override void Initialize(Type type)
{
base.Initialize(type);
this.Description = "数字を入力できます。";
this.DisplayName = "数字入力";
this.Bitmap = new Bitmap(typeof(NumericUpDownToolboxItem),
"OpenFolder.bmp");
}
}
|
ToolStripItemの位置をユーザーが変えられるようにする †
ToolStripのAllowDropプロパティをFalseとして、AllowItemReorderプロパティをTrueとすると、ユーザーがAltキーを押しながらToolStripItemをドラッグすることにより、その位置を変更することができます。
なお、AllowDropプロパティとAllowItemReorderプロパティの両方をTrueとすることはできません。
AllowItemReorderプロパティをTrueとしても移動できないToolStripItemも多く存在します。ToolStripComboBox、ToolStripProgressBar、ToolStripTextBoxなど、ToolStripControlHostを継承したToolStripItemは移動できないようです。
ToolStripItemの位置を保存、復元する方法は、前々号で説明したとおり、ToolStripManager.SaveSettings、LoadSettingsメソッドを使います。
このような方法とは別に、ダイアログを表示してToolStripItemの順番と表示・非表示を変更するサンプルが、MSDNの「ToolStrip のカスタマイズ サンプル」(CustomizeToolStripプロジェクト)にあります。
あるToolStripItemの右側に指定したToolStripItemが常にあるようにする †
例えば、ToolStripにToolStripComboBoxが配置されており、その説明のためにすぐ左側にToolStripLabelを配置した場合、常にToolStripLabelがToolStripComboBoxの左隣にないと意味不明になってしまいます。しかし、ToolStripのAllowItemReorderをTrueとしてユーザーがToolStripItemの位置を自由に変更できる時は、そうなってしまう可能性が十分あります。
これを防ぐために、あるToolStripItemの右側に指定したToolStripItemが常にあるようにする方法を考えてみました。いろいろな方法が考えられますが、ここではToolStripItemのLocationChangedイベントで処理することにします。
下に示す例では、ToolStripにToolStripLabel(toolStripLabel1)とToolStripComboBox(toolStripComboBox1)が配置されているとき、toolStripLabel1の右隣に常にtoolStripComboBox1があるようしています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| | Private Sub toolStripLabel1_LocationChanged( _
ByVal sender As Object, ByVal e As EventArgs) _
Handles ToolStripLabel1.LocationChanged
Dim item As ToolStripItem = CType(sender, ToolStripItem)
If item.Equals(ToolStripLabel1) Then
Dim nextItem As ToolStripItem = ToolStripComboBox1
If Not (nextItem Is Nothing) And _
Not (nextItem.Owner Is Nothing) Then
If nextItem.Owner.Items.IndexOf(nextItem) <> _
item.Owner.Items.IndexOf(item) + 1 Then
nextItem.Owner.Items.Remove(nextItem)
Dim insertIndex As Integer = _
item.Owner.Items.IndexOf(item) + 1
item.Owner.Items.Insert(insertIndex, nextItem)
End If
End If
End If
End Sub
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| | private void toolStripLabel1_LocationChanged(
object sender, EventArgs e)
{
ToolStripItem item = (ToolStripItem)sender;
if (item.Equals(toolStripLabel1))
{
ToolStripItem nextItem = toolStripComboBox1;
if (nextItem != null && nextItem.Owner != null)
{
if (nextItem.Owner.Items.IndexOf(nextItem) !=
item.Owner.Items.IndexOf(item) + 1)
{
nextItem.Owner.Items.Remove(nextItem);
int insertIndex = item.Owner.Items.IndexOf(item) + 1;
item.Owner.Items.Insert(insertIndex, nextItem);
}
}
}
}
|
この方法は、ユーザーが移動することのできないToolStripControlHostを継承したToolStripItemをユーザーが移動できるようにする方法としても使えるかもしれません。
ToolStripに関する取るに足らないTip †
最後に、ここで述べるほどでは無いかもしれないつまらないTipをいくつか紹介します。
ToolStripItemを表示あるいは非表示にする / ToolStripItemが表示されているか調べる †
これは、Visibleプロパティを使えばよさそうですが、そう単純ではありません。ToolStripItemにはこれと同じような目的に使用する、Availableプロパティというものが存在するのです。
両者の違いについてMSDNでは、次のように書かれています(そのまま引用します)。
Available プロパティは、Visible プロパティとは異なります。Available が ToolStripItem を表示するかどうかを示すのに対し、Visible は ToolStripItem およびその親を表示するかどうかを示します。Available と Visible のいずれかを true または false に設定すると、他のプロパティも true または false に設定されます。
つまり、両者は値の設定に関しては全く同じであり、取得に関してのみ異なるということのようです。実際、VS2005のフォームデザイナのプロパティにはVisibleプロパティのみ表示され、Availableプロパティは表示されません。
取得される値がどのように異なるのか、具体的な例で説明しましょう。例えば、あるToolStripにToolStripItemが配置されており、ToolStripItemのVisibleとAvailableプロパティがTrueである場合、そのToolStripのVisibleをFalseに変更すると、ToolStripItemのVisibleもFalseになりますが、AvailableはTrueのままです。また、ToolStripItemをToolStripから削除した時も、VisibleはFalseになりますが、AvailableはTrueのままです。
MSDNによると設定に関しては両者に違いがないように思われますが、実際には違いが見られました。
私の確認した範囲では、別のToolStripItemの子となっているToolStripMenuItemの場合、AvailableプロパティをFalseにすることにより非表示にできますが、VisibleプロパティをFalseにしても非表示にできませんでした(正確には、VisibleプロパティをFalseにしようとしてもできません)。これは、オーバーフローボタンに入ったToolStripItemでもそうであるため、ToolStripItemがオーバーフローメニューに入っていない時はVisibleプロパティが使えるのに、オーバーフローメニューに入っていると使えなくなってしまうという奇妙なことになります。ToolStripMenuItemの表示、非表示をプログラムで行う時は、Availableプロパティを使った方が良さそうです。
メニューにToolTipを表示 †
MenuStripやContextMenuStripでは、今までのメニューと違って、ToolTipを簡単に表示することができます。MenuStripやContextMenuStripのShowItemToolTipsプロパティをTrueにして、ToolStripMenuItem.ToolTipTextプロパティにToolTipとして表示する文字列を指定するだけです。
また、ToolStripItem.AutoToolTipプロパティをTrueとすると、ToolTipTextが設定されていなくても、代わりにTextに設定された文字列がToolTipとして表示されます。
なおMSDNには、ToolStrip.ShowItemToolTipsをTrueとしないとToolTipが表示されないとありますが、MenuStripの場合はShowItemToolTipsをTrueとしなくても、ToolStripMenuItemにToolTipが表示されました。しかし今後のために、MenuStripでもShowItemToolTipsをTrueにしておいた方が良いでしょう。
右端にToolStripItemを配置 †
ToolStripItem.AlignmentプロパティをRightとすることにより、ToolStripの右端にToolStripItemを配置することができます。これを使えば、よくある「ヘルプ」だけがメニューの右端にあるようなアプリケーションも簡単に作れます。
ただし、ToolStrip.LayoutStyleプロパティがTableまたはFlowの場合は、ToolStripItem.Alignmentプロパティが無視されてしまいます。
ToolStripButtonやToolStripMenuItemをクリックすると自動的にチェック状態が変化されるようにする †
ToolStripButtonとToolStripMenuItemにはCheckOnClickプロパティがあり、これをTrueにすることにより、クリックで自動的に状態が変わるようになります。
オーバーフローを有効にする †
ToolStripの幅をだんだん狭めていき、ToolStripItemが表示しきれなくなると、ToolStripの右側に下矢印のボタンが表示され、そのボタンを押すと、ToolStripに表示しきれなくなったToolStripItemがメニュー表示されます。この時、この下矢印のボタンを「オーバーフローボタン」(あるいは「オーバーフローシェブロン」)といい、ToolStripItemがオーバーフローボタンのメニューに入ることを「オーバーフロー(状態になった)」といいます。
オーバーフロー機能を有効にするには、ToolStripのCanOverflowプロパティがTrueで、さらにLayoutStyleプロパティがStackWithOverflowまたは、HorizontalStackWithOverflowやVerticalStackWithOverflowである必要があります。
また、ToolStripItemをオーバーフローボタンのメニューに移動させるかをToolStripItem.Overflowプロパティで指定できます。OverflowプロパティがAsNeededの時は必要な時のみ移動させ、Alwaysの時は常にメニューに表示し、Neverの時はメニューに移動せずに、ToolStripに収まらなくなったら、表示されなくなります。
補足:MSDNではToolStrip.CanOverflowプロパティの説明を、「ToolStrip 内の項目をオーバーフロー メニューに送信できるかどうかを示す値を取得または設定します。」としています。「オーバーフローメニューに送信」という意味が、オーバーフローメニューに移動するということであれば、この説明が正しいのか、疑問です。CanOverflowプロパティがFalseの時、OverflowプロパティがAlwaysのToolStripItemはToolStripに全く表示されません(ToolStrip.LayoutStyleプロパティがTableまたはFlowの時は、表示されます)。これは多分、OverflowがAlwaysのToolStripItemがオーバーフローメニューに移動したが、オーバーフローボタンが表示されなくなったため見えなくなったものと考えられます。つまり、CanOverflowプロパティはオーバーフローボタンを表示するかどうかを指定するものと解釈した方が良さそうです。(説明が正しく、動作が間違っている可能性もありますが。)
ToolStripItemがオーバーフロー状態になったことを知る †
ToolStripItemがオーバーフロー状態になったことを知るためのイベントは存在しません。しかし、MSDNの「方法 : Windows フォームの ToolStrip オーバーフローを管理する」によると、ToolStripのLayoutCompletedイベントが発生した時に、ToolStripItem.Placementプロパティの値を調べて、ToolStripItemがオーバーフロー状態か調べることができるということです。
実際のコードは、例えば、次のようになりそうです。ここでは、toolStripButton1のオーバーフロー状態を監視しています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| | Private toolStripButton1Placement As ToolStripItemPlacement = _
ToolStripItemPlacement.None
Private Sub toolStrip1_LayoutCompleted( _
ByVal sender As Object, ByVal e As EventArgs) _
Handles ToolStrip1.LayoutCompleted
If ToolStripButton1.Placement <> toolStripButton1Placement Then
If ToolStripButton1.Placement = ToolStripItemPlacement.Overflow Then
Console.WriteLine( _
"toolStripButton1がオーバーフロー状態になりました")
Else
If ToolStripButton1.Placement = ToolStripItemPlacement.Main Then
Console.WriteLine( _
"toolStripButton1がオーバーフロー状態ではなくなりました")
End If
End If
toolStripButton1Placement = ToolStripButton1.Placement
Console.WriteLine(DateTime.Now)
End If
End Sub
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| | private ToolStripItemPlacement toolStripButton1Placement =
ToolStripItemPlacement.None;
private void toolStrip1_LayoutCompleted(object sender, EventArgs e)
{
if (toolStripButton1.Placement != toolStripButton1Placement)
{
if (toolStripButton1.Placement == ToolStripItemPlacement.Overflow)
{
Console.WriteLine(
"toolStripButton1がオーバーフロー状態になりました");
}
else if (toolStripButton1.Placement == ToolStripItemPlacement.Main)
{
Console.WriteLine(
"toolStripButton1がオーバーフロー状態ではなくなりました");
}
toolStripButton1Placement = toolStripButton1.Placement;
Console.WriteLine(DateTime.Now);
}
}
|
実際に試してみると分かりますが、toolStripButton1がすでにオーバーフロー状態となっていても、toolStrip1の幅を変えた時に、「オーバーフロー状態になりました」と「オーバーフロー状態ではなくなりました」が連続して表示されることがあります。
補足:ToolStripのオーバーフローボタンの実体は、ToolStripOverflowButtonというToolStripItemであり、ToolStrip.OverflowButtonプロパティで取得することができます。よって、DropDownItemsプロパティで現在オーバーフロー状態となっているすべてのアイテムを取得できそうですが、実際にはできません。しかし、HasDropDownItemsプロパティは使えるようです。
ToolStripの幅に応じてToolStripItemのDisplayStyleを変更する †
MSDNの「ToolStrip サンプル」には、「DynamicOverflowForm」というサンプルが用意されています。これは、ToolStripの幅が狭くなってToolStripItemが表示しきれなくなった時に、ToolStripItemのDisplayStyleプロパティを変更してその幅を縮めることによって、ToolStripItemがオーバーフローとなることをできるだけ防ぐというものです。はじめはすべてのToolStripItemのDisplayStyleがImageAndTextとなっていますが、ToolStripの幅を狭めていくと、ToolStripItemのDisplayStyleがText、Imageと変化していきます。
なかなか面白いサンプルですので、一度お試しください。
コメント †