PrismWPFSample(2)Menuの作り方
Prismを使用したWPFアプリケーション開発で役に立つと思われる項目を一つのアプリケーションにまとめたものを作りました。今回は、モジュールからメニューを追加する方法について書いています。
動作環境:Win10, Visual Studio Community 2017, Prism V7.1.0.431, .NET4.5.2, Prism Template Pack, TraceListeners, WPFLocalizeExtension, OxyPlot
- 1.モジュールにPrismユーザーコントロールを追加
- 2.UserControlをMenuItemに書き換え
- 3.MenuRegionに挿入されるように指定
- 4.M9MenuViewModelのコンストラクターに引数追加
- 5.M9Menu.xaml にMenuItemを追加
- 6.メインアプリのメニューに MenuRegion を設定
- 7.コードで作成する方法
アプリの外観はこんな感じです。
ソリューションはメニューの View が追加された以下のようなものです。
メニューの追加手順は次のようになります。
2.UserControlをMenuItemに書き換え
追加されたM9Menu.xamlをUserControlからMenuItemに変更
Menu.xaml の UserControl を MenuItem に書き換え
<UserControl ....> </UserControl>
>>>修正>>>
<Menutem....> </MenuItem>
Menu.xaml.cs も MenuItem に修正
public partial class M9Menu : UserControl
>>>修正>>>
public partial class M9Menu : MenuItem
3.MenuRegionに挿入されるように指定
MenuRegion に挿入されるように M9Module .cs に記述を追加します。
同時に、M9ViewModel を Menu からアクセスできるように Singleton で登録します。
public class M9Module : IModule { public void OnInitialized(IContainerProvider containerProvider) { var regionManager = containerProvider.Resolve<IRegionManager>(); regionManager.RegisterViewWithRegion("ContentRegion", typeof(M9)); regionManager.RegisterViewWithRegion("MenuRegion", typeof(M9Menu)); } public void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterSingleton<ViewModels.M9ViewModel>(); } }
4.M9MenuViewModelのコンストラクターに引数追加
M9MenuViewModelに引数付きコンストラクターを追加し、メニューからM9ViewModelにアクセスできるようにします。
下記設定でVM9経由でメニューからM9ViewModelにバインドが可能となります。
public M9MenuViewModel(M9ViewModel VM) { VM9 = VM; } private M9ViewModel vM9 ; public M9ViewModel VM9 { get { return vM9; } set { SetProperty(ref vM9, value); } }
5.M9Menu.xaml にMenuItemを追加
M9Menu.xamlにMenuItemを追加してメニューを構成します。
VisualStudioのGUIにはMenuItemは出てこないので、Blendを使用しましょう。
デザイン時の ViewModel に M9MenuViewModel を設定して、バインドの準備をします。
メニューの Header は直接設定してもいいが、M9ViewModel に設定したプロパティとバインドして多言語化します。
メニューを選択時に実行するコマンドもM9ViewModelに作ってVM9経由でバインドします。
<MenuItem ・・・・・・・・・・・・・・・・ xmlns:ViewModels="clr-namespace:Module9.ViewModels" mc:Ignorable="d" prism:ViewModelLocator.AutoWireViewModel="True" Header="{Binding VM9.Title}" d:DataContext="{d:DesignInstance {x:Type ViewModels:M9MenuViewModel}}"> <MenuItem Header="{Binding VM9.HeaderMenu1}" Command="{Binding VM9.CommandMenu1, Mode=OneWay}" IsEnabled="{Binding VM9.MyCModel.CommandEnable}"/> <MenuItem Header="{Binding VM9.HeaderMenu2}" Command="{Binding VM9.CommandMenu2, Mode=OneWay}" IsEnabled="{Binding VM9.MyCModel.CommandEnable}"/> </MenuItem>
6.メインアプリのメニューに MenuRegion を設定
メインアプリのメニューに MenuRegion を設定することで、モジュールに作成したメニューが挿入されます。
挿入される順番のコントロールは前回の方法と同じです。
<Menu DockPanel.Dock="Top" Margin="10,0" > <MenuItem Header="{lex:Loc FILE}"/> <MenuItem Header="{lex:Loc EDIT}"/> <MenuItem Header="{lex:Loc MODULE}" prism:RegionManager.RegionName="MenuRegion" Margin="0"/> </Menu>
7.コードで作成する方法
1.CommonModelにObservableCollection
private ObservableCollection<MenuItem> menuItems = new ObservableCollection<MenuItem>(); public ObservableCollection<MenuItem> MenuItems { get { return menuItems; } set { SetProperty(ref menuItems, value); } }
2.メインアプリでMenuのItemsourceにバインド
3.モジュールのViewModelでMenuItemを作成しCommonModelのObservableCollectionにAdd
作成したサンプルは次の場所に置いてあります。
github.com
次回は、3. ログの保存 について記述したいと思います。