WPF の MenuItem をバンディングで表現してみようのコーナー。ブラウザのブックマークをサンプルにしてみます。
まずはブックマークを表す VM のクラスを用意。
// Bookmark.cspublicclassBookmark {// INotifyPropertyChanged は略publicstring Title {get;set; }publicstring Url {get;set; }public Bookmark(string title,string url) {this.Title = title;this.Url = url; }}
これを元に、メニューの XAML を記述します。
<!-- Window1.xaml --><Windowx:Class="Sample.Window1"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <DockPanel> <MenuDockPanel.Dock="Top"> <MenuItemHeader="ブックマーク(_B)"ItemsSource="{Binding}"DisplayMemberPath="Title"/> </Menu> <WebBrowserx:Name="browser"/> </DockPanel></Window>
あとは DataContext に Bookmark のコレクションを設定します。Application の Startup でやるようにしておきます。
// App.xaml.csprivatevoid App_Startup(object sender,StartupEventArgs e) {Window1 window =newWindow1();ObservableCollection<Bookmark> bookmarks =newObservableCollection<Bookmark>(); bookmarks.Add(newBookmark("bing","http://www.bing.com")); bookmarks.Add(newBookmark("google","http://www.google.co.jp")); bookmarks.Add(newBookmark("yahoo","http://www.yahoo.co.jp")); window.DataContext = bookmarks; window.Show();}
ここまでは簡単だと思います。
さて、これで取り敢えずメニューは表示されるようになりますが、当然項目をクリックしても何の反応もありません。メニュー項目をクリックしたときにその URL に移動する動作が必要です。
入力への応答の記述方法はいくつかありますが、今回は CommandBinding を使用します。
<!-- Window1.xaml --><!-- ブックマークのメニューの部分だけ書き換え --><MenuItemHeader="ブックマーク(_B)"ItemsSource="{Binding}"DisplayMemberPath="Title"> <MenuItem.CommandBindings> <CommandBindingCommand="Favorites"Exected="Navigate"/> </MenuItem.CommandBindings> <MenuItem.ItemContainerStyle> <StyleTargetType="{x:Type MenuItem}"> <SetterProperty="Command"Value="Favorites"/> <SetterProperty="CommandParameter"Value="{Binding}"/> </Style> </MenuItem.ItemContainerStyle></MenuItem>
NavigationCommands.Favorites は基本ライブラリが定義している RoutedCommand であり、Routed の名前通り、コマンドが呼び出されると要素ツリー内の CommandBinding を検索してくれます。つまり、親の MenuItem の CommandBindings に Favorites を設定しておけば子 MenuItem の全ての Command を拾ってくれるって事です。ショートカットキー「Ctrl + I」が定義されているのが難点ですが、ここではおいておきます。
ItemContainerStyle は、ItemsSource を元に作られる各子 MenuItem 自体の Style です。
Favorites コマンドで実行されるメソッド(Navigate)内でどのアイテムがクリックされたか判定するために、CommandParameter を使います。子 MenuItem の DataContext は Bookmark オブジェクトになるため、この DataContext そのものである Bookmark オブジェクトがパラメータになります。
あとは CommandBinding.Executed イベントで呼び出される Navigate メソッドです。
// Window1.xaml.csprivatevoid Navigate(object sender,ExectedRoutedEventArgs e) {Bookmark bm = e.ParameterasBookmark;if (bm !=null) {this.browser.Navigate(newUri(bm.Url)); }}
次のステップはCompositeCollection を使う場合 および階層メニューを表示する場合。
ここ(hongliang.seesaa.net)で公開しているものについて、利用は自由に行って頂いて構いません。改変、再頒布もお好きになさって下さい。利用に対しこちらが何かを要求することはありません。
ただし、公開するものを使用、または参考したことによって何らかの損害等が生じた場合でも、私はいかなる責任も負いません。
あ、こんなのに使ったってコメントを頂ければ嬉しいです。
この広告は90日以上新しい記事の投稿がないブログに表示されております。