.NET Frameworkでお手軽SplitButton・その2
3:ドロップダウンメニューを作成
オリジナルのドロップダウンメニューを作ろうと、コンテキストメニューの代わりにFormを表示させようとするとフォーカスが表示されたフォームに移動してしまい、なんだか不格好です。フォームのような柔軟さを兼ね備えたメニューを作るにはToolStripDropDownが最適です。ちなみにAnchorSelectControlはControlの派生クラスで、このControlに対してデザインを施すことになります。
anchorbtn.cs
private ToolStripDropDown dropdown;
private AnchorSelectControl asctrl;
public AnchorButton()
{
this.Appearance = Appearance.Button;
AnchorStyle = AnchorStyles.Left | AnchorStyles.Top;
dropdown = new ToolStripDropDown();
asctrl = new AnchorSelectControl();
dropdown.Items.Add(new ToolStripControlHost(asctrl));
dropdown.Closed += new ToolStripDropDownClosedEventHandler(dropdown_Closed);
this.TextAlign = ContentAlignment.MiddleLeft;
}
4:ドロップダウンメニューの挙動を作成
ボタンをクリックするとメニューが表示されるわけですが、このメニューが閉じられるとき、マウスカーソルがボタンの上にある時は何回やっても閉じられないため、ToolStripDropDownClosedでは、マウスカーソルの位置に応じて処理を変えるようにしています。
dropdown.cs
private void dropdown_Closed(object sender, ToolStripDropDownClosedEventArgs e)
{
// メニューの設定を反映
AnchorStyle = asctrl.AnchorResult;
if (!ClientRectangle.Contains(PointToClient(MousePosition))) {
Checked = false;
}
}
protected override void OnCheckedChanged(EventArgs e)
{
base.OnCheckedChanged(e);
if (this.Checked == false) {
dropdown.Close();
} else {
asctrl.AnchorResult = AnchorStyle;
dropdown.Show(this,
ClientRectangle.Right - 100 - dropdown.GripMargin.Left,
ClientRectangle.Bottom + 1 - dropdown.GripMargin.Top);
}
}
これを応用すれば、いわゆるカラーピッカーボタンも簡単に作れます。ただし、色数分のボタンを作成するとシステムに負担がかかるため、Paintイベントでボタンを描画することで、ボタンの挙動を擬似的に再現させた方がよいでしょう。
2007/10/24