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

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

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

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

原文

訳文

Advanced MVVM Scenarios Using the Prism Library 5.0 for WPF(外部サイト)

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

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

コマンド

Commands

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

Interaction Triggers and Commands

非同期相互作用を扱う

Handling Asynchronous Interactions

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

User Interaction Patterns

しばしば、アプリケーションは、ユーザーに、イベントの発生を通知する、 あるいは、操作を続行する前に、確認を要求する必要があります。 これらの相互作用は、多くの場合、アプリケーションで、単純に、それらに変更を知らせるために、 あるいは、それらから、単純な応答を得るために、設計された簡潔な相互作用です。 これらの相互作用のいくつかは、ユーザーにとって、ダイアログボックスやメッセージボックスを表示する、 あるいは、それらが、ユーザーに非モーダルに見えるかもしれない時のように、トースト通知、 あるいは、ポップアップウィンドウが表示されるときのような、モーダルに見えるかもしれません。

これらの場合、相互作用するための複数の方法が、ユーザーにありますが、 この方法で、MVVMに基づいたアプリケーションをそれらに実装することは、明確に分離した関係を保つことが、困難な場合があります。 例えば、非MVVMアプリケーションでは、あなたは、多くの場合、UIのコード・ビハインド・ファイルで、 単純にユーザーに応答を促すために、MessageBoxクラスを使用するでしょう。 MVVMアプリケーションでは、ViewとView Modelの間で、それが関係の分離を壊すため、これは適切でありません。

MVVMパターンの観点から、View Modelは、ユーザーと相互作用を開始するための、そして、どんな応答でも、 利用し、そして、処理するための役割を果たします。ユーザーが使用することで、実際に、相互作用を管理するための役割を果たします。 どんな、ユーザー・エクスペリエンスでも適切です。 View Modelに、実装されるプレゼンテーション・ロジック間の関係の分離を維持する。 そして、ユーザー・エクスペリエンスは、ビューによって、実装される。テスタビリティと柔軟性を改善するのを助けます。

MVVMパターンのこれらの種類のユーザーとの相互作用を実装するための2つの一般的な方法があります。 1つの方法は、ユーザーと相互作用を開始する、View Modelによって使用することができるサービスを実装することです。 それによって、ビューの実装で、その独立を維持します。他の方法は、ユーザーと相互作用する目的を表すView Modelで、 これらのイベントに結合し、そして、相互作用の視覚的な測面を管理する、 ビューのコンポーネントと一緒に、呼び出したイベントを使用します。 これらのそれぞれの方法は、次のセクションで説明されています。

相互作用サービスを使用する

Using an Interaction Service

この方法では、View Modelは、メッセージボックスを通して、ユーザーと相互作用を開始するために、相互作用サービスコンポーネントに依存しています。 この方法は、別々のサービスコンポーネントの相互作用で、視覚的な実装のカプセル化による、関係の明確な分離とテスタビリティをサポートします。 一般的に、View Modelは、相互作用サービス・インターフェイス上で依存関係を持っています。 それは、頻繁に、依存関係注入やサービス・ロケーターを通じて、参照を、相互作用サービスの実装に取得します。

View Modelが、相互作用サービスに参照を取得したあと、それは、プログラム上で、必要があるときは、ユーザーとの相互作用を要求することができます。 次の図に示すように、相互作用サービスは、相互作用の視覚的な測面を実装しています。 View Modelで、インターフェイス参照を使用することは、ユーザー・インターフェイスの実装要件によって、使用されるための異なる実装を提供します。 例えば、WPFのための相互作用サービスの実装は、アプリケーションのプレゼンテーション・ロジックを、さらに再使用できます。

相互作用サービスは、相互作用の視覚的な測面を実装しています。

次のコードの例に示すように、ユーザーModalインタラクションで相互作用するために、実行が進行することができる前に、特定の応答を得るために、 ユーザーは、モーダル・ポップアップウィンドウやMessageBoxが存在する場所のような、 相互作用サービスを使用して、ブロッキング・メソッド呼び出しを使用して、同期方法で実装することができます。


var result =
    interactionService.ShowMessageBox(
        "Are you sure you want to cancel this operation?", 
        "Confirm", 
        "あなたは、あなたが、この操作をキャンセルしたいと確認しますか?",
        "確認します",
        MessageBoxButton.OK );
if (result == MessageBoxResult.Yes)
{
    CancelRequest();
}

しかしながら、この方法の1つの欠点は、それが同期プログラミングモデルを強要することです。 代わりの非同期実装は、View Modelのために、相互作用が完了する際に実行するためのコールバックを提供できます。 次のコードは、この方法を説明します。


interactionService.ShowMessageBox(
    "Are you sure you want to cancel this operation?",
    "Confirm",
        "あなたは、あなたが、この操作をキャンセルしたいと確認しますか?",
        "確認します",
    MessageBoxButton.OK,
    result =>
    {
        if (result == MessageBoxResult.Yes)
        {
            CancelRequest();
        }
    });

相互作用サービスを実装するとき、非同期の方法は、実装するために、 モーダルと非モーダル相互作用を提供することによって、さらに大きな柔軟性を提供します。 例えば、WPFでは、MessageBoxクラスは、ユーザーと本当のモーダル相互作用を実装するために、使用することができます。

対話要求オブジェクトを使用する

Using Interaction Request Objects

MVVMパターンで、簡単に、ユーザーとの対話処理を実装する他の方法は、 View Modelが、対話要求オブジェクトとビュー内の動作の結合を通して、 ビューそれ自身に対話要求ディレクトリを作成できます。対話要求オブジェクトは、対話要求の内容、 そして、その応答、そして、ビューイベントを経由した情報のやりとりをカプセル化します。 ビューは、相互作用のユーザー・エクスペリエンス部分を開始するために、これらのイベントに登録します。 次の図に示すように、ビューは、一般的に、相互作用のユーザー・エクスペリエンスを、動作にカプセル化します。 それは、View Modelにより提供される対話要求オブジェクトにデータ結合されています。

ユーザーと相互作用するために対話要求オブジェクトを使用する

ユーザーと相互作用するために対話要求オブジェクトを使用する

Using an interaction request object to interact with the user

この方法は、単純な(さらに、柔軟な)View ModelとViewの間で明確な分離を維持する仕組みを提供します。- ビューを、相互作用の視覚的な測面に、完全に、カプセル化している間、 View Modelは、どんな、必要とされるユーザーとの対話処理でも含まれている、アプリケーションのプレゼンテーション・ロジックをカプセル化できます。 期待されるViewを通してのユーザーとの相互作用が含まれているView Modelの実装は、簡単に、テストできます。 そして、UIデザイナーは、相互作用のために、異なるユーザー・エクスペリエンスをカプセル化する、 異なる動作の使用を通して、ビューの中で相互作用を、どのように実装するか選択する、多くの柔軟性を持っています。

この方法は、View Modelを監視する、そのビューの状態変化を反映でき、 そして、2つのデータの通信の間の双方向のデータ結合を使用して、 MVVMパターンと同一です。対話要求オブジェクト内の相互作用の非ビジュアル要素のカプセル化、 そして、相互作用の対応する動作の使用を管理する視覚的な要素は、 コマンド・オブジェクトの方法に極めて類似しています。そして、コマンドの動作は使用されます。

このアプローチは、Prismで採用されたアプローチです。 Prismライブラリは、IInteractionRequestなインターフェイスとInteractionRequest<T>クラスを通して、 直接、このパターンをサポートしています。IInteractionRequestインターフェイスは、相互作用を開始するイベントを定義します。 ビューの動作は、このインターフェイスを結合し、そして、それが公開するイベントに登録します。InteractionRequest<T>クラスは、 IInteractionRequestインターフェイスを実装しています。 そして、View Modelを提供するために、相互作用を開始するために、そして、要求のために、 そして、必要に応じて、コールバック・デリゲートで、コンテクストを指定するために、2つのRaiseメソッドを定義します。

View modelから対話要求を開始する

Initiating Interaction Requests from the View Model

InteractionRequestクラスは、対話要求の間のビューとView Modelの相互作用を調整します。 Raiseメソッドは、View Modelが、相互作用を開始し、そして、コンテクスト・オブジェクト(T型の)と相互作用が完全なものになったあと、 呼び出されるコールバック・メソッドを指定できます。コンテクスト・オブジェクトは、 ユーザーと相互作用の間使用されるViewに、データと状態を渡すために、View Modelを提供します。 コールバック・メソッドが、指定される場合、コンテクスト・オブジェクトは、View Modelに戻されます。; これは、View Modelに戻される相互作用の間に、ユーザーが、どんな変更も作成できます。


public interface IInteractionRequest
{
    event EventHandler<InteractionRequestedEventArgs> Raised;
}
 
public class InteractionRequest<T> : IInteractionRequest
    where T : INotification
{
    public event EventHandler<InteractionRequestedEventArgs> Raised;
 
    public void Raise(T context)
    {
        this.Raise(context, c => { });
    }

    public void Raise(T context, Action<T> callback)
    {
        var handler = this.Raised;
        if (handler != null)
        {
            handler(
                this, 
                new InteractionRequestedEventArgs(
                    context, 
                    () => { if (callback != null) callback(context); } ));
        }
    }
}

Prismは、一般的な対話要求の筋書きをサポートしている、定義済みのコンテキスト・クラスを提供しています。INotificationインターフェイスは、 すべてのコンテキスト・オブジェクトのための使用されます。それは、アプリケーションにおいて、ユーザーに重要なイベントを通知するために、 対話要求が使用されるとき、使用されます。それは、2つのプロパティを提供します。-タイトルと内容-それは、ユーザーに表示されます。一般的に、通知は一方向です。 このように、それは、ユーザーが、相互作用の間、これらの値を変更するかもしれないことを予期していません。 Notificationクラスは、このインターフェイスの既定の実装です。

IConfirmationインターフェイスは、INotificationインターフェイスを拡張して、第3のプロパティを追加します。 -確認します-それは、ユーザーが、操作を確認、あるいは、否定することを示すために使用されます。IConfirmationの実装により提供されたConfirmationクラスは、 ユーザーが、ユーザーからyes/noの応答を取得したい場所、MessageBoxスタイルの相互作用を実装するために使用されます。あなたは、どんなデータでもカプセル化するために、 INotificationインターフェイスを実装している、ユーザー定義したコンテクスト・クラスを定義することができます。 そして、あなたが必要とする状態は、相互作用をサポートしています。

InteractionRequest<T>クラスを使用するために、View Modelクラスは、InteractionRequest<T>クラスのインスタンスを作成するでしょう。 そして、それに、データ結合するビューを提供するために、読取専用プロパティを定義します。 View Modelが、要求を開始したいとき、それは、Raiseメソッドを呼び出し、コンテクスト・オブジェクト、そして、必要に応じて、コールバック・デリゲートに渡します。


public InteractionRequestViewModel()
{
    this.ConfirmationRequest = new InteractionRequest<IConfirmation>();
    …
    // Commands for each of the buttons. Each of these raise a different interaction request.
    //各々のボタンに命令します。
    // これらの各々は、異なる対話要求を発生させます。
    this.RaiseConfirmationCommand = new DelegateCommand(this.RaiseConfirmation);
    …
}

public InteractionRequest<IConfirmation> ConfirmationRequest { get; private set; }

private void RaiseConfirmation()
{
    this.ConfirmationRequest.Raise(
        new Confirmation { Content = "Confirmation Message", Title = "Confirmation" },
        c => { InteractionResultMessage = c.Confirmed ? "The user accepted." : "The user cancelled."; });
    }
}

インタラクティブ性のクイックスタートは、IInteractionRequestインターフェイスとInteractionRequest<T>クラスが、 ViewとView Modelの間で、ユーザー対話処理の実装を、どのように使用するかを説明します。(InteractionRequestViewModel.csを参照してください)。

相互作用ユーザー・エクスペリエンスを実装する動作を使用する

Using Behaviors to Implement the Interaction User Experience

対話要求オブジェクトが、論理的な相互作用を表すため、相互作用のための正確なユーザー・エクスペリエンスは、ビューで定義されます。動作は、多くの場合、 相互作用のためのユーザー・エクスペリエンスをカプセル化するために、使用されます。;これは、UIデザイナーが、適切な動作を選択し、 そして、View Modelで、それを対話要求オブジェクトに結合することができます。

ビューは、対話要求イベントを見つけるために、そして、その次に、要求のための適切な視覚的な表示を表現するために、設定する必要があります。 トリガは、特定のイベントが発生するたびに、動作を開始するために使用されます。

公開される対話要求オブジェクトへの結合で、View Modelで、Blendにより提供される標準的なEventTriggerは、 対話要求イベントを監視するために使用することができます。 しかしながら、Prismライブラリは、InteractionRequestTriggerという名前のユーザー定義したEventTriggerを定義します。 それは、自動的に、適切な、IInteractionRequestインターフェイスのRaisedイベントを結合します。 これは、必要なExtensible Application Markup Language (XAML)の量を減らします。 そして、不注意で、誤ったイベント名を入力する可能性を減らします。

イベントが呼び出されたあと、InteractionRequestTriggerは、指定された動作を呼び出します。 WPFのために、Prismライブラリは、 PopupWindowActionクラスを提供します。それは、ユーザーにポップアップウィンドウを表示します。ウィンドウが表示されるとき、 そのデータ・コンテクストは、対話要求のコンテクスト・パラメータに設定されます。PopupWindowActionクラスのWindowContentプロパティを使用して、 あなたは、ポップアップウィンドウで、表示されるビューを指定することができます。 ポップアップウィンドウのタイトルは、コンテクスト・オブジェクトのTitleプロパティに結合されます。

備考

既定では、PopupWindowActionクラスで表示されるポップアップウィンドウの特定の型は、 コンテクスト・オブジェクトの型に依存します。Notificationコンテキスト・オブジェクトのための、DefaultNotificationWindowは表示され、 Confirmationコンテキスト・オブジェクトのためのある間、DefaultConfirmationWindowは表示されます。DefaultNotificationWindowは、 通知を表示する単純なポップアップウィンドウを表示します。また、DefaultConfirmationWindowが、 ユーザーの応答を取り込むために、AcceptとCancelボタンを含む間、 PopupWindowActionクラスのWindowContentプロパティを使用して、 ユーザー定義したポップアップウィンドウを指定することによって、あなたは、この動作を上書きすることができます。

次の例は、InteractionRequestTriggerとPopupWindowActionが、インタラクティブ性クイックスタート内で、 ユーザーに、確認ポップアップウィンドウを表示するために、どのように使用するか、示します。


<i:Interaction.Triggers>
    <prism:InteractionRequestTrigger SourceObject="{Binding ConfirmationRequest, Mode=OneWay}">
        <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True"/>
    </prism:InteractionRequestTrigger>
</i:Interaction.Triggers>

備考

PopupWindowActionは、3つの重要なプロパティを持っています。IsModal、それが、trueに設定されるとき、 モーダルにするためのポップアップを設定します。;CenterOverAssociatedObject、 それは、trueに設定されると、親のウィンドウに中央揃えされるポップアップを表示します。 最後に、WindowContentプロパティは、指定されません。したがって、DefaultConfirmationWindowが、示されるでしょう。

PopupWindowActionは、DefaultNotificationWindowのデータ・コンテクストとして、 NotificationオブジェクトのContentプロパティを表示する、Notificationオブジェクトを設定します。 ユーザーが、ポップアップ・ウィンドウを閉じた後、コールバック・メソッドによって、どんな更新された値でも、 一緒に、コンテクスト・オブジェクトは、View Modelに戻されます。インタラクティブ性クイックスタートの確認の例で、 OKボタンがクリックされると、DefaultConfirmationWindowは、 trueに指定されたConfirmationオブジェクトで、Confirmedプロパティを設定するための役割を果たします。

異なるトリガと動作は、他の相互作用の仕組みをサポートするために、定義することができます。 PrismのInteractionRequestTriggerとPopupWindowActionクラスの実装は、 あなた自身のトリガと動作の開発のための基盤として使用することができます。

高度な構築と接続

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