環境
VisualStudio2017(C#)
.NetFramework 4.7.2
Prism.Wpf 6.3.0
ReactiveProperty 5.0.0
前提・実現したいこと
ViewModelを持つUserControl上にあるボタンを押下した際に、Bindingされたコマンドの
内容をFormのViewModelに記述したい
使い所は、複数画面を持つシステムの、各画面にファンクションキー12個分のボタンを持つ
UserControlを配置し、各ボタンの処理は各画面のViewModelに記述したい
そういった処理を行いたい場合、どのように行ったらよろしいでしょうか?
試してみたソース
UserControlのXAML(上の画像とは異なります)
C#
1<UserControl x:Class="UserControlSample.Views.PrismUserControl1" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:prism="http://prismlibrary.com/" 5 prism:ViewModelLocator.AutoWireViewModel="True"> 6 <Button Width="50" Height="50" Command="{Binding CommandExecute}" Content="ボタン" /> 7</UserControl>
UserControlのViewModel
C#
1using Prism.Mvvm; 2 3namespace UserControlSample.ViewModels 4{ 5 public class PrismUserControl1ViewModel : BindableBase 6 { 7 public PrismUserControl1ViewModel() 8 { 9 } 10 } 11}
FormのXAML
C#
1<Window x:Class="UserControlSample.Views.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:prism="http://prismlibrary.com/" 5 xmlns:u="clr-namespace:UserControlSample.Views" 6 Title="{Binding Title}" 7 Width="525" 8 Height="350" 9 prism:ViewModelLocator.AutoWireViewModel="True"> 10 <StackPanel> 11 <u:PrismUserControl1 /> 12 </StackPanel> 13</Window>
FormのViewModel
C#
1using Prism.Mvvm; 2using Reactive.Bindings; 3using System; 4 5namespace UserControlSample.ViewModels 6{ 7 public class MainWindowViewModel : BindableBase 8 { 9 public ReactiveCommand CommandExecute { get; set; } = new ReactiveCommand(); 10 11 public MainWindowViewModel() 12 { 13 this.CommandExecute.Subscribe(Xxx); 14 } 15 16 private void Xxx() 17 { 18 // ボタン押下時にこの処理が行われるようにしたいが、このソースだとここは動かない 19 Console.WriteLine("終了ボタン押下"); 20 } 21 } 22}
試したこと
UserControlのViewModelを削除し、Viewだけにすれば、上記「終了ボタン押下」が実行されるが
UserControlにViewModelがあると、Xxxメソッドが呼び出されない
【追記】
コマンド部分を別クラスに分けて MainWindowViewModel / PrismUserControl1ViewModel の両方に注入する方法。
UserControlプロジェクトにコマンドのみのクラス追加
C#
1using Reactive.Bindings; 2 3namespace PrismUserControl1 4{ 5 public class FunctionCommand 6 { 7 public ReactiveCommand CommandExecute { get; set; } = new ReactiveCommand(); 8 } 9}
UserControlのViewModelにあるコンストラクタで上記コマンドのクラスを受け取るようにする
C#
1using Prism.Mvvm; 2 3namespace PrismUserControl1.ViewModels 4{ 5 public class PrismUserControl1ViewModel : BindableBase 6 { 7 // PrismUserControl1 でバインドして使えるようにアクセサを設ける。 8 public FunctionCommand FunctionCommand { get; set; } 9 10 public PrismUserControl1ViewModel() 11 { 12 } 13 14 public PrismUserControl1ViewModel(FunctionCommand functionCommand) 15 { 16 // アクセサに設定する。 17 FunctionCommand = functionCommand; 18 } 19 } 20}
FormのViewModelもUserControlと同様にコンストラクタでFunctionComandを受け取るようにする
C#
1using Prism.Mvvm; 2using PrismUserControl1; 3using System; 4 5namespace UserControlSample.ViewModels 6{ 7 public class MainWindowViewModel : BindableBase 8 { 9 // PrismUserControl1 でバインドして使えるようにアクセサを設ける。 10 public FunctionCommand FunctionCommand { get; set; } 11 12 public MainWindowViewModel() 13 { 14 } 15 16 public MainWindowViewModel(FunctionCommand functionCommand) 17 { 18 // アクセサに設定する。 19 FunctionCommand = functionCommand; 20 21 // CommandExecuteに処理のわりあて 22 FunctionCommand.CommandExecute.Subscribe(Xxx); 23 } 24 25 private void Xxx() 26 { 27 Console.WriteLine("ボタン押下"); 28 } 29 } 30}
ConfigureContainerでFunctionCommandを注入できるようにする
c#
1using Microsoft.Practices.Unity; 2using Prism.Modularity; 3using Prism.Unity; 4using PrismUserControl1; 5using System.Windows; 6using UserControlSample.Views; 7 8namespace UserControlSample 9{ 10 internal class Bootstrapper : UnityBootstrapper 11 { 12 protected override DependencyObject CreateShell() 13 { 14 return Container.Resolve<MainWindow>(); 15 } 16 17 protected override void InitializeShell() 18 { 19 Application.Current.MainWindow.Show(); 20 } 21 22 protected override void ConfigureModuleCatalog() 23 { 24 var moduleCatalog = (ModuleCatalog)ModuleCatalog; 25 //moduleCatalog.AddModule(typeof(YOUR_MODULE)); 26 } 27 28 protected override void ConfigureContainer() 29 { 30 base.ConfigureContainer(); 31 32 // FunctionCommandを設定できるようにする 33 Container.RegisterType<FunctionCommand>(new ContainerControlledLifetimeManager()); 34 } 35 } 36}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/06/30 00:03
2018/06/30 01:43 編集
退会済みユーザー
2018/06/30 14:56
退会済みユーザー
2018/06/30 14:57
退会済みユーザー
2018/06/30 14:58
2018/06/30 16:17
退会済みユーザー
2018/07/01 01:07