ホーム > コンピュータ > C# > WPF in C# > Prism

ベクトルドロー・レベルゼロ+

Prism Library 5.0 for WPFを使用する高度なMVVMの筋書き 02[C# WPF Prism]

新規作成日 2015-10-15
最終更新日

原文

訳文

パターンと実践 ディベロパー・センター

Microsoft Prism Library 5.0 for WPFの開発者のガイド原文サイト)から:

コマンド

Commands

コマンドは、コマンドの実装ロジックをそのUIの表示から分離する方法を提供します。 データ結合や動作は、ビューとコマンドがView Modelで提供される、要素を宣言的に関連付けるための方法を提供します。 MVVMパターンを実装する(原文リンク) コマンド(原文リンク)の項目で、 View Modelのコマンド・オブジェクトやコマンド・メソッドが、 どのように、実装できるか、そして、それらが、特定のコントロールによって提供される、組込みCommandプロパティを使用して、 ビューでコントロールを、どのように呼び出すことができるか、説明しました。

WPFのルーティングされたコマンド:

それが、コマンド・オブジェクトとして実装する必要があることに、注意します。あるいは、MVVMパターンのコマンド・メソッドは、 ルーティング・コマンドという名前のWPFの組み込みのコマンドの実装と、 いくぶん異なります。WPFのルーティング・コマンドは、UIツリー内の要素を通じて、それらを送ることによって、コマンドのメッセージを提供します。(特に論理ツリー(原文リンク))。 その結果、コマンド・メッセージは、フォーカスされた要素から、あるいは、明示的に指定された対象とする要素に、UIのツリーの上や下に送られます。; 既定では、それらは、ビューに関連付けられたView Modelのような、UIツリーのコンポーネントの外にに送られません。 しかしながら、WPFのルーティング・コマンドは、View Modelクラスにコマンド呼び出しを転送するために、 ビューの分離コードで定義されるコマンド・ハンドラを使用することができます。

複数の要素で構成されたコマンド

Composite Commands

多くの場合、View Modelによって定義されるコマンドは、関連するビューでコントロールに結合されます。 そのため、ユーザーは、直接、ビュー内からコマンドを呼び出すことができます。 しかしながら、場合によっては、あなたは、アプリケーションのUIで親ビューのコントロールから、 1つ以上のView Modelで、コマンドを呼び出すことができるようにしたいかもしれません。

例えば、あなたのアプリケーションは、ユーザーが、同時に複数の項目を編集できる場合、 あなたは、ユーザーが、アプリケーションのツールバーやリボンのボタンによって、表示される単一のコマンドを使用して、すべての項目を保存したいかもしれません。 この場合、すべてを保存コマンドは、View Modelインスタンスによって、次の図で示すそれぞれの項目のために、実装されるSaveコマンドの各々を呼び出します。

SaveAll複合コマンドを実装する

SaveAll複合コマンドを実装する

Implementing the SaveAll composite command

Prismは、CompositeCommandクラスによる、この筋書きをサポートします。 CompositeCommandクラスは、複数の子のコマンドから構成されるコマンドを示します。 複合コマンドが呼び出されるとき、その子のコマンドの各々は、順番に呼び出されます。 それは、UIの単一のコマンドとして、コマンドのグループを表示する必要がある場所、 あるいは、あなたが、論理コマンドを実装するために、複数のコマンドを呼び出したい場所の状況で、役立ちます。

例えば、CompositeCommandクラスは、buy/sellビューでSubmit Allボタンによって、コマンドが表示した、 SubmitAllOrdersを実装するために、株トレーダーの参考になる実装(株トレーダーRI)で使用されます。 ユーザーが、Submit Allボタンをクリックすると、それぞれのbuy/sellトランザクションによって、 実行される、それぞれのSubmitCommandで定義されます。

CompositeCommandクラスは、子のコマンドのリストを保持します(DelegateCommandインスタンス)。 CompositeCommandクラスのExecuteメソッドは、単純に、それぞれの子のコマンド上で、順番にExecuteメソッドを呼び出します。 同様に、CanExecuteメソッドは、それぞれの子のコマンドのCanExecuteメソッドを呼び出します。 しかし、子のコマンドを、どれも実行することができない場合、CanExecuteメソッドは、falseを返します。 言い換えると、既定では、すべての子のコマンドが、実行することができるとき、CompositeCommandは、実行することだけができます。

子コマンドの登録と解除

Registering and Unregistering Child Commands

子のコマンドは、RegisterCommandとUnregisterCommandメソッドを使用して、登録、 あるいは、未登録されます。株トレーダーRI(のための)の例では、次のコードの例に示すように、 それぞれの売り買いの注文のためのSubmitとCancelコマンドは、 SubmitAllOrdersとCancelAllOrders複合コマンドで登録されます。 (OrdersControllerクラスを参照してください)。


// OrdersController.cs
commandProxy.SubmitAllOrdersCommand.RegisterCommand(
                        orderCompositeViewModel.SubmitCommand );
commandProxy.CancelAllOrdersCommand.RegisterCommand(
                        orderCompositeViewModel.CancelCommand );

備考

前述のcommandProxyオブジェクトは、静的に定義される送信と取消・複合コマンドにインスタンス・アクセスを提供します。 詳細については、クラス・ファイルStockTraderRICommands.csを参照してください。

Active Childビューの上でコマンドを実行する

Executing Commands on Active Child Views

多くの場合、あなたのアプリケーションは、アプリケーションのUIの内で、子のビューのコレクションを表示する必要があります。 それぞれの子のビューは、順番に、その場所で、対応するView Modelを持っています。1つ以上のコマンドを実装しているかもしれません。 複合コマンドは、配置されるアプリケーションのUIとヘルプ内の子のビューで、どのように、それらが、親ビュー内に実装されるか、 実装されるコマンドを表示するために、使用することができます。これらの筋書きに対応するために、 PrismのCompositeCommandとDelegateCommandクラスは、Prism内で動作するように設計されていました。

Prismの領域(項目、領域(原文リンク)、ユーザー・インターフェイスの構成(原文リンク)で記述される)アプリケーションのUIで、 論理プレースホルダに関連付けられる子のビューのために提供されます。 それらは、多くの場合、子のビューの具体的なレイアウトをそれらの論理プレースホルダ、そして、UI内の位置から、分離するために使用されます。 領域は、特定のレイアウト・コントロールに、添付されている、名前を付けられたプレースホルダに基づいています。

次の図は、それぞれの子のビューが、EditRegionという名前の領域に追加された例を示しています。 そして、UIデザイナーは、その領域の中で、ビューを配置するために、Tabコントロールを使用することを選択しました。

Tabコントロールを使用して、EditRegionを定義する

Tabコントロールを使用して、EditRegionを定義する

Defining the EditRegion using a Tab control

親のビュー・レベルの複合コマンドは、多くの場合、コマンドが子のビュー・レベルで呼び出される座標で使用されます。 場合によっては、あなたは、すべての表示されるビューのためのコマンドが、実行されることを望みます。 Save Allコマンドの例として、以前に解説されたように、他の場合には、あなたは、コマンドが、アクティブ・ビューの上だけで、実行されることを望むでしょう。 この場合、複合コマンドは、アクティブと考えられるビューの上でだけで、子のコマンドを実行します。;それは、アクティブでないビューの上で、子のコマンドを実行しないでしょう。 例えば、それは、次の図に示すように、アプリケーション・ツールバーやリボンの上で、現在、アクティブなアイテムだけを拡大する、Zoomコマンドを実装するといいかもしれません。

Tabコントロールを使用して、EditRegionを定義する

Tabコントロールを使用して、EditRegionを定義する

Defining the EditRegion using a Tab control

この筋書きに対応するために、Prismは、IActiveAwareインターフェイスを提供します。IActiveAwareインターフェイスは、実装者がアクティブであるとき、 trueを返す、IsActiveプロパティを定義し、そして、IsActiveChangedイベントは、アクティブ状態が変更されるたびに発生します。

あなたは、子のビューやView Modelで、IActiveAwareインターフェイスを実装することができます。 それは、主に、領域の中で、子のビューのアクティブな状態を追跡するために使用されます。ビューが、アクティブかどうかは、 特定の領域コントロールの範囲内で、ビューを調整する、領域アダプタで決定されます。 先に示した、Tabコントロールのために、領域アダプタがあります。 例えば、それは、アクティブとして、現在選択されたタブ内のビューを設定します。

また、DelegateCommandクラスは、IActiveAwareインターフェイスを実装しています。CompositeCommandは、 コンストラクタで、monitorCommandActivityパラメータをtrueに指定することによって、 (CanExecuteステータスに加えて)子のDelegateCommandsの有効なステータスを評価するために、 設定することができます。このパラメータが、trueに設定されるとき、CanExecuteメソッドのための戻り値が、決定されるとき、 そして、Executeメソッドの範囲内で、子のコマンドを実行するとき、 CompositeCommandクラスは、それぞれの子のDelegateCommandのアクティブ・ステータスを考慮するでしょう。

monitorCommandActivityパラメータが、trueのとき、CompositeCommandクラスは、次に示す動作を見せます。:

  • CanExecute.
  • すべてのアクティブなコマンドを実行できる場合にのみ、trueを返します。非アクティブである子コマンドは、全く考慮されません。

  • Execute.
  • すべてのアクティブなコマンドを実行します。非アクティブである子コマンドは、全く考慮されません。

あなたは、あなたの子のView Modelで、領域で、子のビューが、アクティブ、あるは、非アクティブになるとき、あなたは、通知される、 IActiveAwareインターフェイスを実装することによって、先程説明された例を実装するために、この機能を使用することができます。 子のビューが、アクティブ状態を変更するとき、あなたは、子のコマンドのアクティブ・ステータスを更新することができます。 続いて、ユーザーが、ズーム複合コマンドを呼び出すとき、子のビューの上のアクティブなZoomコマンドは、呼び出されます。

コレクション内のコマンド

Commands Within Collections

項目のコレクションを表示するとき、ビューの中で、あなたが、多くの場合、遭遇する、他の一般的な筋書きは、 あなたが、それぞれの項目のために、UIを必要とするとき、親のビュー・レベルで、(項目レベルの代わりに)コレクションの中で、コマンドに関連付けられます。

例えば、次の図で示されるアプリケーションにおいて、ビューは、ListBoxコントロールの項目のコレクションを表示します。 そして、それぞれの項目を表示するために使用されるデータ・テンプレートは、Deleteボタンを定義します。 それは、ユーザーが、コレクションから、それぞれの項目を削除できます。

コレクション内の結合コマンド

コレクション内の結合コマンド

Binding commands within collections

View Modelが、Deleteコマンドを実装するため、難問は、それぞれの項目のためのUIに、Deleteボタンを、View Modelで実装されるDeleteコマンドに接続することです。 ListBox内の各々の項目のデータ・コンテクストは、Deleteコマンドを実装する親のView Modelの代わりに、コレクション内の項目を参照するため、困難が発生します。

この問題への1つの方法は、結合が、親のコントロールと比較し、そして、データ・テンプレートと比較しないことを確実に行うために、 ElementNameプロパティを使用して、データ・テンプレートで、親のビューのコマンドに、ボタンを結合することです。次のXAMLは、この技術を説明します。


<Grid x:Name="root">
    <ListBox ItemsSource="{Binding Path=Items}">
        <ListBox.ItemTemplate>
            <DataTemplate>
  <Button Content="{Binding Path=Name}"
          Command="{Binding ElementName=root, Path=DataContext.DeleteCommand}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

データ・テンプレートのボタン・コントロールの内容は、コレクションの中で、項目に関するNameプロパティに結合されます。 しかしながら、ボタンのためのコマンドは、ルート要素のデータ・コンテクストを通じて、Deleteコマンドに結合されます。 これは、ボタンが、項目のレベルの代わりに、親のビュー・レベルで、コマンドに結合できます。 あなたは、コマンドが適用される予定の項目を指定するために、CommandParameterプロパティを使用することができます。 あるいは、あなたは、現在選択された項目を(CollectionViewを通して)操作するために、コマンドを実装することができます。

トリガとコマンドの相互作用

Interaction Triggers and Commands

非同期相互作用を扱う

Handling Asynchronous Interactions

ユーザーとの対話処理パターン

User Interaction Patterns

高度な構築と接続

Advanced Construction and Wire-Up

MVVMアプリケーションをテストする

Testing MVVM Applications

詳細情報

More Information

Copyright (C) 2011-2016 kukekko All Rights Reserved.
kukekko@gmail.com
ご連絡の際はアドレスの@は半角にしてください。 また、お問い合わせページのURLの明記をお願いします。
「掲載内容は私自身の見解であり、所属する組織を代表するものではありません 」。
inserted by FC2 system