質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

3回答

8020閲覧

[WPF][MVVM][Prism]異なるxamlのCommandを実行したい。

nabesann203

総合スコア45

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

1クリップ

投稿2018/01/16 13:08

編集2018/01/16 13:27

お世話になります。
WPF+Prismフレームワークでの開発を勉強しています。
Prismの性質上、Moduleごとにxamlを分ける箇所の実装方法(Commandの記法)について、ご教授いただきたく。

◆理解できている部分
ViewにてCommandを明記し、関連するViewModel上の同Commandを実行できる事は理解しました。
(下記①のボタンを押下時に、②のExecuteCommnadが実行される。)


①View.xaml

XML

1<UserControl x:class ~略~> 2 <Button Content="実行" Command="{Binding ExecCommand}" /> 3</UserControl>

②ViewModel.cs

C#

1public class FindFormViewModel { 2 // 実行したいコマンド 3 public DelegateCommand ExecCommand { get; private set; } 4 // コンストラクタ 5 public FindFormViewModel() { 6 ExecCommand = new DelegateCommand(Execute, CanExec); 7 } 8 private bool CanExec() { ~略~ } 9 private void Execute() { ~略~ } 10}

◆質問事項(理解できていない部分)
上記のExecuteCommnadを、別のxamlから呼び出したいです。
具体的には、MenuItem(メニューバー)から実行したいですが、
★の箇所について、色々試しても分からず。。

Menu.xaml

XML

1<UserControl x:class ~略~> 2 <Menu> 3 <MenuItem Header="ファイル"> 4 <MenuItem Header="ここからも実行できるよ" Command="★ここにどう書く??★" /> 5 </MenuItem> 6 </Menu> 7</UserControl>

<xamlの関連が記載が漏れていたため追記。>
View.xamlMenu.xamlはそれぞれ独立しており、Shellのxamlからそれぞれを参照しています。

Shell.xaml

XML

1<Window> 2 <Grid> 3 <!-- Menu.xaml --> 4 <ContentControl prism:RegionManager.RegionName="MenuRegion" /> 5 <!-- View.xaml --> 6 <ContentControl prism:RegionManager.RegionName="ViewRegion" /> 7 </Grid> 8</Window>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

亀レスですが要望通りのことをしようとすると以下のようなことをすれば出来ます。

まず、コマンドを共有したい View で同じ ViewModel の型が割り当てられるようにします。

ViewModelLocatorProvider.Register<View, FindFormViewModel>(); ViewModelLocatorProvider.Register<Menu, FindFormViewModel>();

この時点でコマンドは参照できるようになりますが、おそらく ViewModel のインスタンスが異なります。一緒にしたい場合には、DI コンテナにシングルトンとして登録します。Unity の場合には以下のようになります。

Container.RegisterType<FindFormViewModel>(new ContainerControlledLifetimeManager());

こんな感じで出来ますが ViewModel のインスタンスがシングルトンになることで被る影響の方が大きい気がします。

因みに、コマンドを共通化したいのは多分それぞれのボタンやメニューを選択したときに実行するロジックを共通化したいのだと思いますが、そういう場合は以下のようにするほうが理想的です。

class SomeModelClass { public void ExecuteLoginc() { } } // これが View.xaml 用の VM class FindFormViewModel { private readonly SomeModelClass _someModelClass; public FindFormViewModel(SomeModelClass someModelClass) { _someModelClass = someModelClass; } // コマンドの定義は省略 // 以下のメソッドがコマンドの Execute に割当たってるとする private void CommandExecute() => _someModelClass.ExecuteLogic(); } // これが Menu.xaml 用の VM class MenuViewModel { private readonly SomeModelClass _someModelClass; public FindFormViewModel(SomeModelClass someModelClass) { _someModelClass = someModelClass; } // コマンドの定義は省略 // 以下のメソッドがコマンドの Execute に割当たってるとする private void CommandExecute() => _someModelClass.ExecuteLogic(); }

そして、この SomeModelClass のインスタンスを DI コンテナにシングルトンで登録する感じです。

Container.RegisterType<SomeModelClass>(new ContainerControlledLifetimeManager());

投稿2018/01/19 16:30

okazuki0130

総合スコア185

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nabesann203

2018/01/21 09:47 編集

ありがとうございました。亀レスなんてとんでもないです。 質問しても、ここの人達は手法は教えてくれない所なんだなーと思ってた所でしたので、、 (考え方は指摘もらえましたので、ありがたかったですが。) |ViewModel のインスタンスがシングルトンになることで被る影響の方が大きい気がします。 |因みに、コマンドを共通化したいのは~  PrismはModule単位にMVVMの構成が組めるので、あえてシングルトンにして、  「そのViewでやりたい処理はそのViewに任せる。」って考え方もありかなーって思いました。  抽象的で申し訳ないですが、被る影響についてもう少し教えてもらえますか。
okazuki0130

2018/01/29 07:15

たとえば画面を破棄して再表示した場合でも古いデータが残ってしまうとかですねー。
guest

0

ベストアンサー

こんにちは。

DataContextを使ったViewとViewModelの関係については理解していますか?
PrismだとひょっとするとUnityなどで勝手にViewModelがロードされているかもしれませんが、XAMLでバインド表記されているCommandoは対象DataContextのCommandへのバインドです。
ですので、別のXamlから実行したいのであれば同一のインスタンスをバインドすればよいです。

上記についてわからない点があれば、まずはその部分から学習されるのが宜しいと思います。
PrismというよりWPFの基本的なViewとViewModelの関係性だと思います。

投稿2018/01/16 13:54

Tak1wa

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nabesann203

2018/01/17 10:42

回答ありがとうございます。 確かにPrismでは色々省略出来るため、根本は理解できていないかもしれません。 少しずつ確認をしようと思いますが、今回の質問は「Prismを使用した場合はどう実装するか」です。 「Prismでは特別な手法は用意されてないので、WPFの基本的な実装しかない」という回答で間違いないでしょうか?
Tak1wa

2018/01/17 10:45

「PrismでコマンドなどViewModelの実装を簡略化するものなどはあるが、今回の問題はWPFの基本的な実装に関するものでPrismは関係ない」です
nabesann203

2018/01/17 10:48

分かりました。ありがとうございました。
guest

0

Menu が View の中にあるなら RelativeSource で行けるんだろうと思いますが、省略しすぎてて情報が少なすぎるのでこれ以上は書けません。

投稿2018/01/16 13:12

Zuishin

総合スコア28656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nabesann203

2018/01/16 13:29

回答ありがとうございます。 右クリックメニュー(ContextMenu)のようなものであれば、 ご回答の通り相対指定(1つ上の階層)でいけるのではと理解しております。 が、追記しました通り、MenuとViewは独立しており、難しいのではと考えています。
Zuishin

2018/01/16 13:41

情報が少なすぎるので同意も否定もできません。
nabesann203

2018/01/16 13:46

恐縮ですが、どのような情報が少なすぎるのか教えていただけますでしょうか。
Zuishin

2018/01/16 13:51

これにコードを補ってコマンドを使うことはできます。 しかしそれはあなたの現在のコードとかけ離れたものになるかもしれません。 それくらい欠損しています。 どのようなというレベルではなく全然何もかも足りません。
nabesann203

2018/01/17 10:48

何を聞いても解決に繋がらない回答しか頂けなかったので、低評価を付けました。
Zuishin

2018/01/17 10:56 編集

どうぞ。 解決につながらなかったのは何度聞いても質問者がろくな情報を出さなかったからですが、それがわかるには時間がかかるでしょう。いや、わからないでしょうね。
Zuishin

2018/01/17 11:16

一つの事実は、普通のまともな質問者なら三十分で解決している問題が、私だけではなく Tak1wa さんまで出てきて結局解決しなかったということです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問