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

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

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

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

MVVM

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

WPF

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

Q&A

0回答

1458閲覧

WPF/MVVMでのユーザーコントロールのイベントの実装方法がわからない

ry188472

総合スコア74

C#

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

MVVM

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

WPF

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

0グッド

0クリップ

投稿2020/12/02 08:55

編集2020/12/02 08:56

いままでWinformsでしか開発してこなかったので、WPFでの開発に戸惑っています。正直「わからないことがわからない」レベルで躓いていて、検索結果を見ても???という状態です。お詳しい方がいればご教授いただけると幸いです。

前提条件

  • Visual Studio 2017 C# 7.3
  • WPFの各画面は Prism と ReactiveProperty で開発しようとしている

やりたいこと

  • WPFで、各画面に共通して独自のツールバーを画面上部に出したい。
  • ツールバーにあるボタンの役割は各画面で同じ。例えば「検索ボタン」なら検索処理、「保存ボタン」なら保存処理が行われる。
  • ボタンが押されたときの処理は各画面で若干違う。

わからないこと

  • ユーザーコントロールのイベントを、それが配置された画面で処理する方法がわからない

(Winformsのようにユーザーコントロールのボタンのイベントを直接ハンドルすることはできない?)

知りたいこと

  • そもそも、子コントロールや子画面で起きた処理をどのクラスが責任を持って処理すべきか自信を持ってないです。

今回のような例で、ユーザーコントロールに配置されたボタンが押されたときの処理はどのように実装すべきですか?
思いついたのは以下です。
0. 独自ツールバーの処理は親画面で責任を持つ:ユーザーコントロールにICommandを実装する。ユーザーコントロールはどのボタンが押されたかの引数と一緒にPublishする。親画面はxamlでユーザーコントロールのCommandをSubscribeするメソッドを1つ定義し、Commandに付帯する引数でどのボタンが押されたか識別して処理を振り分ける
⇒ ボタンが増えたときにif文をいろんなコードに追加する必要がありそう。
0. 独自ツールバーの処理は独自ツールバー側で完結させる:各ボタンの機能ごとにインターフェイスを定義する(ISavable, ISearchable等)。ボタンごとにどういった処理を行うのかの実装を、親画面のModelに対してインターフェイス実装する。ユーザーコントロールは初期化されるときに画面側からDIで親画面のModelを受け取り、各ボタンのCommandのSubscribe時にそのインターフェイスのメソッドを実行する。
⇒ ユーザーコントロールのVM⇒親画面のModelで処理⇒処理結果で親画面のModelの状態変更⇒親画面のVM経由で親画面のView状態変更、という流れ方をするはず。これがMVVM的にあっているかどうかがわからない
0. EventAggregatorで親画面-子コントロール間のイベント購読管理する?

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

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

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

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

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

ry188472

2020/12/03 06:25

URLのサンプルを見させてもらいました。ありがとうございます。 ただ、どうしていまいちとされるのかはわかりませんでした。 親画面のModelのメソッドを子コントロールのVMから叩かせるのが一番妥当なのかなと思ったんですが・・・
hihijiji

2020/12/03 07:11

多くのサンプルが画面に親子関係を持たせず、Viewは独立性が高くなっていると思います。 Modelは親画面のじゃなく、検索や保存のイベントを受け渡しするための専用の物を用意するのが良いです。 実装はEventAggregatorを使ってもICommand型のプロパティをもつModelでもなんでもいいです。 "独自ツールバーの処理は独自ツールバー側で完結させる"がMVVM的には良い感じで収まりやすいですそうですが、親子というよりイベント発生側とイベント購読側と考えたほうがいいかな。
ry188472

2020/12/03 08:07

自分の理解では、 ①検索や保存などの非同期処理を持つクラスを作る ②画面ごとのModelがそれらのインスタンスと処理中/完了済みや結果などのプロパティを持つ ③画面のViewModelが画面ごとのModelの状態変化に伴ってViewに表示等するためのバインド用のプロパティを持つ で、子コントロールに②のModelを渡すようなイメージでいました。 「Modelは親画面のじゃなく、検索や保存のイベントを受け渡しするための専用の物を用意するのが良いです。」というのは、②の画面ごとのModelはつくらずに①の処理側で状態管理すれば十分、みたいな理解であってますか?
hihijiji

2020/12/03 08:14

画面同士の依存性を排除することが目的です。
ry188472

2020/12/03 08:31

親画面のModelを子コントロールが受け取れるようにするとユーザーコントロール(配置される側・どれが親画面になるかわからない)が親画面Model(配置する側・なんのコントロールを配置するかわかっている)に依存するためよくなくて、親画面の制御(?)によってDIで処理クラス(画面等に関係なく処理を行うクラス)を子コントロール側につっこんで子コントロールのViewModelで処理クラスの状態監視し、それを親画面のViewModelで購読するほうがよい、ってことですか? 子コントロールのViewModel→親画面のViewModelに通知できるならそもそも親画面のViewModelでボタン押下を購読するほうがシンプルな気がしますが・・・うーむ
hihijiji

2020/12/03 09:48 編集

最初にアドレスしたようにサンプルを沢山見て動かしてみることです。 経験も定石も不足している状態でどれだけ考えてもいい方法は出てきません。 今一とは書きましたが、間違っているわけではないので兎に角、組んでみる方が いいかもしれません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問