私が WPF で不満に思っていることの1つに、「DropDownButton が無い」があります。過去に何回かこの話題を記事にしていますが、それくらい私にとっては大問題です。Windows Forms の ToolStripDropDownButton みたいなコントロールが、なんで WPF には無いのかと小一時間。
一応、ToggleButton と ContextMenu を使えばそれっぽく実装できます。ToggleButton がチェック状態のときに ContextMenu を表示してやればいいです。ただ、これ毎回実装するの面倒。
実装を使い回したいけど、DropDownButton コントロールを自作するのもなんかイヤです。「いつか標準で提供されるかも…」という淡い期待が邪魔をして、自作する気にはなりません。テンプレート書くの大変なんだもの。
よろしい、ならば添付ビヘイビアだ。
ということで、ToggleButton を DropDownButton 化する添付ビヘイビア作ってみました。
using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; namespace DropDownButtonSample { public static class DropDownMenuBehavior { public static readonly DependencyProperty DropDownMenuProperty = DependencyProperty.RegisterAttached( "DropDownMenu", typeof(ContextMenu), typeof(DropDownMenuBehavior), new PropertyMetadata(null, OnDropDownMenuChanged)); private static void OnDropDownMenuChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { var button = sender as ToggleButton; if (button == null) { return; } var dropDownMenu = e.NewValue as ContextMenu; if (dropDownMenu == null) { return; } dropDownMenu.Placement = PlacementMode.Bottom; dropDownMenu.PlacementTarget = button; button.SetBinding(ToggleButton.IsCheckedProperty, new Binding("IsOpen") { Source = dropDownMenu, }); } public static void SetDropDownMenu(ToggleButton button, ContextMenu dropDownMenu) { button.SetValue(DropDownMenuProperty, dropDownMenu); } public static ContextMenu GetDropDownMenu(ToggleButton button) { return button.GetValue(DropDownMenuProperty) as ContextMenu; } } }
こんな風に使います。
<Window x:Class="DropDownButtonSample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:DropDownButtonSample" Title="MainWindow" Height="350" Width="525"> <DockPanel LastChildFill="False"> <ToolBar DockPanel.Dock="Top"> <ToggleButton Content="操作"> <local:DropDownMenuBehavior.DropDownMenu> <ContextMenu> <MenuItem Header="開く"/> </ContextMenu> </local:DropDownMenuBehavior.DropDownMenu> </ToggleButton> </ToolBar> </DockPanel> </Window>
それっぽく動いたので満足です。
自作コントロールだったら、ツールバー内に配置したときのデザインとか考える必要があります。その点、添付ビヘイビアなら ToggleButton をそのまま使うので、ツールバー専用のテンプレートは不要。自作コントロールに比べて、はるかに手間が少なくて済みます。
ホント、添付ビヘイビアって便利。