Home > C# > UIパターン > Prism > Prismチュートリアル

Prism Library 5.0 for WPFを使用した状態に基づいたナビゲーションのQuickStart

新規作成日 2016-06-07
最終更新日

※サンプルコードのダウンロードは、原文リンクから行ってください。

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

State-Based Navigation QuickStart Using the Prism Library 5.0 for WPF(原文

Microsoft Prism Library 5.0 for WPFの開発者のガイドから:

状態に基づいたナビゲーションのQuickStartサンプルは、Model-View-ViewModel(MVVM)パターンと一緒に、 WPFのVisual State Manager(VSM)とPrism Libraryでを使用して、ナビゲーションを実演します。 この方法は、状態と状態の間で移行するアニメーションを定義する異なるアプリケーションの状態を定義するために、 アプリケーションが、持っているVisual State Managerを使用しています。; 状態に関連付けられるアニメーションは、指定されたタイムラインの持続時間のためアクティブな間、有効です。

アプリケーション設計の1つの重要な測面は、ナビゲーションの右側を取得しています。 アプリケーションのナビゲーションを定義するために、 あなたは、アプリケーションの画面、相互作用と視覚的な外観を設計する必要があります。

実際の使い方

Business Scenario

状態に基づいたナビゲーションのQuickStartのメイン・ウィンドウは、チャット・アプリケーションのサブセットを紹介します。 このウィンドウは、ユーザー接続リストを表示します。ユーザーは、それらが接続する、異なるViewの間で交替することができます。: リスト、アイコン、あるいは、接続の詳細。それらが現れると、ユーザーの連絡先からのメッセージが、表示されます。 連絡先の詳細ビューでは、あなたは、メッセージを、その連絡先に送信することができます。 次に示す図は、クイックスタートのメイン・ウィンドウを示しています。

状態に基づいたナビゲーションのQuickStartユーザー・インターフェイス

状態に基づいたナビゲーションのQuickStartユーザー・インターフェイス

State-Based Navigation QuickStart user interface

QuickStartを構築して、そして、実行する

Building and Running the QuickStart

QuickStartは、ソースコードとして運びます。-これは、あなたがそれを実行する前に、それをコンパイルする必要があることを示しています。 このクイックスタートは、Microsoft Visual Studio 2012以降と.NET Framework 4.5.1を必要とします。

状態に基づいたナビゲーションのQuickStartを構築して、実行するには、

To build and run the State-based Navigation QuickStart

  • Visual Studioでは、ソリューション・ファイルQuickstarts\State-Based Navigation_Desktop\State-Based Navigation.slnを開きます。
  • Buildメニュー内で、Rebuild Solutionをクリックします。
  • QuickStartを実行するために、F5を押してください。

実装の詳細

Implementation Details

QuickStartは、VSMを使用するナビゲーションを実装するための重要な要素と考慮すべき問題を強調します。 VSMの詳細については、MSDNのVisualStateManagerクラス(原文)を参照してください。 このQuickStartでは、ほとんどのUIは、いくつかのクラス(ChatViewとSendMessagePopupViewクラス)です。 そして、表示される視覚的な状態、そして、どのように1つの状態から他に移行するか決定します。 いくつかの状態は、View内で要素の表示属性を変更します。 いくつかの状態は、使用可能に変更します、そして、いくつかの状態は、コンポーネントをアクティブにします。 この項目では、次の図に表示されるQuickStartの主要な成果物を説明します。

状態に基づいたナビゲーションのQuickStartの概念ビュー

状態に基づいたナビゲーションのQuickStartの概念ビュー

State-Based Navigation QuickStart conceptual view

Extensible Application Markup Language (XAML)ファイルが、いくつかの状態に含まれていることに注意してください。 ビューの状態がグループ化されます。(あなたは、状態をViewと比較することができます)各々のグループに1つの有効な状態だけが存在できます。 その結果、アプリケーションの状態は、4つの視覚的な状態(それぞれ視覚的な状態のグループ)の組合せです。 異なる移行は、viewによって駆動されます。前述の図の中で、各々の移行の矢印の上で、表現される状況は、1つの状態から他のものへ移行を起動するものです。 アニメーションの定義は、移行と動作に関連付けられます。また、それらを起動し、ViewのXAMLファイルで定義します。

備考

QuickStartでは、VisualStateGroupにつき、2つの状態だけがあります。これは必須ではありません。; しかしながら、あなたが、より多くの状態を持っている場合、移行ロジックは、より複雑である可能性があります。

次に示す図は、アプリケーションの状態を示しています。そして、視覚的な状態は、それらを作成するために、有効です。

アプリケーションの状態とそれらの有効な視覚的な状態

アプリケーションの状態とそれらの有効な視覚的な状態

Application states and their active visual states

論理ビュー(状態)

Logical Views (States)

一般的に、論理ビューは、ユーザーにアプリケーションと相互作用させる、UI要素のフォ-ムです。 このアプリケーションでは、論理ビューは、実際に、まさに、一つの物理Viewが移行する状態です。 状態は、1つのユーザー・コントロールやどんな複雑な設定のユーザー・コントロールでも含めることができます。 状態に基づいたナビゲーションのQuickStartは、次に示す、状態を持っています。: リストView、アイコンViewと連絡先View。さらに、QuickStartは、送信メッセージの子Viewがあります。

これらの論理ビューの定義のほとんどは、Views/ChatViews.xamlファイルに含まれています。 次に示すコードは、XAMLファイル内の異なる論理ビューを示しています。

XAML

<ContentControl x:Name="MainPane"
            HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
            Grid.Row="2">

    <Grid>
        ...
        <!-- Buttons (shared between all views) -->
        <Grid x:Name="ButtonsPanel" Grid.Row="0">
        ...
            <RadioButton x:Name="ShowAsListButton" ... />
            <RadioButton x:Name="ShowAsIconsButton" ... />
            <Button x:Name="ShowDetailsButton" ... />
        </Grid>

        <!-- Contacts view-->
        <ListBox x:Name="Contacts"
                ItemsSource="{Binding ContactsView}"
                Style="{Binding Source={StaticResource ContactsList}}"
                HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="2" Grid.RowSpan="3" Visibility="Collapsed"/>

        <!-- Avatars view-->
        <ListBox x:Name="Avatars"
                ItemsSource="{Binding ContactsView}"
                Style="{Binding Source={StaticResource AvatarsList}}"
                HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="2"  Grid.RowSpan="3" Visibility="Collapsed"
                AutomationProperties.AutomationId="AvatarsView"/>

        <!-- Details view -->
        <Grid x:Name="Details"
                Background="White" Visibility="Collapsed"
                HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.RowSpan="5">
            ...
        </Grid>

    </Grid>
</ContentControl>

Viewが、Collapsedに設定されているVisibilityプロパティを持っていることに注意してください。 これは、各々のviewに構成されているコントロールが、表示されない、そして、それらのための空間が確保されないことを示しています。 このように、異なるビューの間のナビゲーションは、まず最初に折りたたまれた、すべてのViewから構成されています。

関連する視覚的な状態に移動すると、アニメーションが起動するでしょう。それは、それらの表示属性を、Visibleに変更します。 (そして、先程の状態のためのアニメーションは、停止されるでしょう。 結果として、その関連する論理ビューのための表示属性が、最初のCollapsed値にリセットされます。)。

視覚的な状態の間の移行

Transitions Between Visual States

移行は、どのように、1つのViewから他のものへ移行するかを決定します。 DataStateBehaviorビヘイビアは、条件つきのプロパティ・バインディングが、TrueやFalseに評価するかどうかに基づいて、 2つの視覚的な状態の間で、切り換えるために使用されています。 DataStateBehaviorビヘイビアで、あなたは2つの値を比較することができます。 1つの値は、バインディングからもたらされます。あなたは、明示的に比較する、他の値を宣言することができます。 2つの値が、等しい場合、Trueのための視覚的な状態の指定は、アクティブにされます。 2つの値が、等しくない場合、Falseに指定された視覚的な状態は、アクティブにされます。 次のコードは、チャットViewに、定義されるビヘイビアを示しています。

XAML

<i:Interaction.Behaviors>
    <ei:DataStateBehavior Binding="{Binding ShowDetails}" 
                            Value="True" 
                            TrueState="ShowDetails" FalseState="ShowContacts"/>
    <ei:DataStateBehavior Binding="{Binding IsChecked, ElementName=ShowAsListButton}" 
                            Value="True" 
                            TrueState="ShowAsList" FalseState="ShowAsIcons"/>
    <ei:DataStateBehavior Binding="{Binding ConnectionStatus}" 
                            Value="Available" 
                            TrueState="Available" FalseState="Unavailable"/>
    <ei:DataStateBehavior Binding="{Binding SendingMessage}" 
                            Value="True" 
                            TrueState="SendingMessage" FalseState="NotSendingMessage"/>
</i:Interaction.Behaviors>

結合されたプロパティの値に依存することに注意してください。異なる状態が、表示されます。 別に連絡先リスト、アイコン、詳細ビューから、アプリケーションを使用可能や使用不可にするための、状態があります。 (サービスが利用できないとき、)そして、ビジー指標をアクティブ化、あるいは、非アクティブために、(アプリケーションがビジー状態である場合)。

一般的に、アニメーションは、1つの状態から他のものまで、滑らかな移行を作成するために起動されます。 異なる状態に移動するとき、ソースViewは、隠され、そして、対象は表示されます。状態に関連付けられているアニメーションは、永続的です。 次のコード例は、移行の間、発生する素早くページをめくるアニメーションを表示します。移行に関連付けられるアニメーションは、一時的です。

XAML


<VisualStateGroup x:Name="VisualizationStates">

    <VisualStateGroup.Transitions>

        <VisualTransition From="ShowAsIcons" To="ShowAsList">
            <Storyboard SpeedRatio="2">
                ...
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Angle" Storyboard.TargetName="rotate">
                     <EasingDoubleKeyFrame KeyTime="0:0:0" Value="360"/>
                     <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="270"/>
                     <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="90"/>
                     <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>
                 </DoubleAnimationUsingKeyFrames>

                 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Visibility)" Storyboard.TargetName="Avatars">
                      <DiscreteObjectKeyFrame KeyTime="0:0:0.5" >
                          <DiscreteObjectKeyFrame.Value>
                                 <Visibility>Collapsed</Visibility>
                          </DiscreteObjectKeyFrame.Value>
                                </DiscreteObjectKeyFrame>
                  </ObjectAnimationUsingKeyFrames>

                  <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Visibility)" Storyboard.TargetName="Contacts">
                          <DiscreteObjectKeyFrame KeyTime="0:0:0.5">
                                <DiscreteObjectKeyFrame.Value>
                                     <Visibility>Visible</Visibility>
                                </DiscreteObjectKeyFrame.Value>
                                </DiscreteObjectKeyFrame>
                    </ObjectAnimationUsingKeyFrames>

            </Storyboard>
        </VisualTransition>


        <VisualTransition From="ShowAsList" To="ShowAsIcons" ... />

    </VisualStateGroup.Transitions>
    ...
</VisualStateGroup>

状態は、異なる視覚的な状態のグループにグループ化されます。 状態グループの状態は、1つだけ、一度に表示されることができます。 これらの理由のため、ShowAsList状態(連絡先リストView)、そして、ShowAsIcon状態(アイコンView)は、互いに排他的です。 ShowingDetailsとNotShowingDetails状態は、異なるグループに属しています。; その結果、アプリケーションは、同時に、ShowAsIconsとShowingDetails状態にあることができます。 この場合、ShowingDetails状態は、アイコンViewが前景と重複重複します。; NotShowingDetails状態に移行するとき、詳細な情報Viewは、折りたたまれます。 そして、先程のView、アイコンViewは、表示されます。 このように、それが、背後で、有効ため、あなたは、返すために、先程の状態を格納する必要はありません。

対話の要求

Interaction Requests

対話の要求は、ユーザーと相互作用を要求するために、View Modelのための抽象的な方法を提供します。 対話の要求の詳細については、高等なMVVMの筋書きの中の対話の要求オブジェクトを使用するを参照してください。 QuickStartは、2つの異なる状況のために、対話の要求を使用します。:メッセージを送受信する:

受けるメッセージ。View Modelのコードは、相互作用をサポートするオブジェクトを作成します。 (Viewで情報をやりとりするために、ペイロードでイベントを呼び出すことによって、)そして、プロパティを通してそれらを公開します。 それで、それらは、Viewで利用されることができます。 次のChatViewModelクラスからのコード例では、ShowReceivedMessageRequestプロパティが定義されることに注意します。 そして、その次に、Messageインスタンスを発生させるために、OnMessageReceivedイベントハンドラで使用されます。

C#


public IInteractionRequest ShowReceivedMessageRequest
{
    get { return this.showReceivedMessageRequest; }
}

private void OnMessageReceived(object sender, MessageReceivedEventArgs a)
{
    this.showReceivedMessageRequest.Raise(a.Message);
}

View側で、それは、対話の要求を検出する必要があります。 そして、その次に、要求のために、適切な表示を提示します。 カスタムInteractionRequestTriggerは、 自動的に、結合されたIInteractionRequestのRaisedイベントを購読します。 次のコード例、ChatView.xamlファイルに配置し、これを表示します。

XAML


<prism:InteractionRequestTrigger SourceObject="{Binding ShowReceivedMessageRequest}">
    <cb:ShowNotificationAction TargetName="NotificationList" />
</prism:InteractionRequestTrigger>

状態に基づいたナビゲーションのQuickStartでは、 一時的に、受信メッセージをコレクションに加えるために、カスタムShowNotificationActionクラスが、使用されます。 そして、ポップアップウィンドウのDataContextとして、このコレクションを設定します。 このように、メッセージは、非表示にする前の決定された時間で、非モーダルのウィンドウの中で、表示されるでしょう。

メッセージの送信。送信メッセージ・ウィンドウを表示するには、SendMessageRequest対話の要求が、使用されます。 次のChatViewModelからのコード例では、表示されるSendMessageメソッド内で、この対話の要求のRaiseメソッドは、呼び出されます。

C#


public IInteractionRequest SendMessageRequest
{
    get { return this.sendMessageRequest; }
}

public void SendMessage()
{
    var contact = this.CurrentContact;
    SendMessageViewModel viewModel = new SendMessageViewModel();
    viewModel.Title = "Send message to " + contact.Name;

    this.sendMessageRequest.Raise(
        viewModel,
        sendMessage =>
        {
            if (sendMessage.Confirmed)
            {
                this.SendingMessage = true;

                this.chatService.SendMessage(
                    contact,
                    sendMessage.Message,
                    result =>
                    {
                        this.SendingMessage = false;
                    });
            }
        });
}

View側で、対話の要求が発見されるとき、PopupWindowActionは、 次のChatView.xamlファイルからのコード例に示すように、SendMessagePopViewポップアップウィンドウを表示します。

XAML


<prism:InteractionRequestTrigger SourceObject="{Binding SendMessageRequest}">
    <prism:PopupWindowAction IsModal="True"> 
        <prism:PopupWindowAction.WindowContent>
            <vs:SendMessagePopupView />
        </prism: PopupWindowAction.WindowContent>
    </prism:PopupWindowAction>
</prism:InteractionRequestTrigger>

PopupWindowActionアクションのIsModalプロパティは、指定するために、trueに設定されることを注意してください。 この相互作用は、モーダルにする必要があります。 表示されるビューを指定するには、相互作用が、発生するとき、WindowContentプロパティを使用します。

チャット・サービス

Chat Service

チャット・サービスは、連絡先とそれらのデータを取り出すために使用されます。; また、それは、他のユーザーからメッセージを送受信するために、使用されます。 次のコード例は、サービス・インターフェイスを表示します。

C#


public interface IChatService
{
    event EventHandler ConnectionStatusChanged;
    event EventHandler<MessageReceivedEventArgs> MessageReceived;
    bool Connected { get; set; }
    void GetContacts(Action<IOperationResult<IEnumerable<Contact>>> callback);
    void SendMessage(Contact contact, string message, Action<IOperationResult> callback);
}

サービスには、次に示すメンバーが含まれています。:

  • Connectedプロパティ。このプロパティは、サービスの状態を格納します。:Connected/Disconnected。
  • ConnectionStatusChangedイベントハンドラ。このイベントハンドラは、接続状態の変化に反応します。
  • MessageReceivedイベントハンドラ。新しいメッセージを受信すると、このイベントハンドラが反応します。
  • GetContactsメソッド。このメソッドは、ユーザーの連絡先を検索します。
  • SendMessageメソッド。このメソッドは、メッセージをユーザーの連絡先に送信します

サービスは、他のユーザーから、入力メッセージをシミュレーションするために、タイマーを持っています。 タイマーのカチカチいう音ごとに、メッセージは、ランダムな抽選に基づいて受け取る、33パーセントの可能性があります。 さらに、また、タイマーは、接続の欠落をシミュレーションするために使用されています。; しかしながら、この出来事の可能性は、非常に弱い(1/150)です。 あなたは、OnTimerTickイベントハンドラを紹介する、次のコードの例でこれを見ることができます。

C#


private void OnTimerTick(object sender, EventArgs args)
{
    if (this.Connected)
    {
        var coinToss = this.random.Next(3);
        if (coinToss == 0)
        {
            this.ReceiveMessage(
                          this.GetRandomMessage(this.random.Next(receivedMessages.Length)),
                        this.GetRandomContact(this.random.Next(this.contacts.Count)));
        }
        else
        {
            coinToss = this.random.Next(150);
            if (coinToss == 0)
            {
                this.Connected = false;
            }
        }
    }
}

カスタム・ビヘイビア

Custom Behaviors

ビヘイビアは、自己内蔵型の機能の単位です。ビヘイビアには、2つの種類があります。:

  • ビヘイビアは、呼出しの概念を持っていません。;その代わりに、それは、オブジェクトに、アドオンのように動作します。
  • トリガと動作は、より密接な呼出しモデルです。

追加の機能は、簡単に、XAMLや、デザイナーを通して、オブジェクトに添付することができます。 それらは、UIでイベントやトリガを取り扱うために、反応することができます。 次のビヘイビアは、QuickStartで使用され、そして、定義されています。(Infrastructure/Behaviorsフォルダに配置されます):

  • ShowNotificationAction。このカスタム・ビヘイビアは、UIで対象とする要素に通知を押し込むために、View Modelを提供します。 QuickStartでは、チャット・メッセージを表示するために、使用されます.それは、UIの右下角で、ユーザーによって受診されます。

次の動作は、Prism.Interactivityが射影するPrism Libraryの一部です。:

  • PopupWindowAction。この具体的な実装は、指定されたウィンドウやデータ・テンプレートで設定される既定のものを示しています。

受入検査

Acceptance Tests

状態に基づいたナビゲーションのQuickStartには、受入検査が含まれている分離したソリューションが含まれています。 受入検査では、あなたが、一連の手順に従うとき、アプリケーションが、どのように動作する必要があるかを説明します。 あなたは、さまざまな使い方をする、アプリケーションの機能の挙動を調べるために、受入検査を使用することができます。

状態に基づいたナビゲーションのQuickStartの受入検査を実行するために

To run the State-Based Navigation QuickStart acceptance tests

  1. Visual Studioでは、ソリューション・ファイルQuickstarts\State-Based Navigation_Desktop\State-Based Navigation.Tests.AcceptanceTest\State-Based Navigation.Tests.AcceptanceTest.slnを開きます。
  2. ソリューションを構築します。
  3. Test Explorerを開きます。
  4. ソリューションを構築した後、Visual Studioは、テストを捜し出します。受入検査を実行するために、Run Allボタンをクリックします。

結論

Outcome

あなたは、ウィンドウのQuickStartを参照する必要があります。 そして、テストは、自動的に、アプリケーションと相互作用します。 テスト実行の終了時に、あなたは、すべてのテストが渡されたことを確かめる必要があります。

詳細情報

More Information

Prismに含まれる、他のナビゲーション・トピックについて学ぶためには、次のトピックを参照してください。:

Prismに含まれる、他のコードサンプルについて学ぶためには、次のトピックを参照してください。:

このエントリーをはてなブックマークに追加

Home PC C# Illustration

Copyright (C) 2011 Horio Kazuhiko(kukekko) All Rights Reserved.
kukekko@gmail.com
ご連絡の際は、お問い合わせページのURLの明記をお願いします。
「掲載内容は私自身の見解であり、所属する組織を代表するものではありません。」