nuits.jp blog

C#, Xamarin, WPFを中心に書いています。Microsoft MVP for Development Technologies。

【Xamarin.Forms】汎用的なBehavior集ライブラリを作ってる

ふと思い立って、汎用的なBehaviorライブラリを作ってます。

とりあえず作っているのは

  • Eventを指定してEventが発生したら何かする抽象Behavior
  • Eventが発生したらCommandを実行するBehavior
  • DisplayAlertを表示してCommandを実行するBehavior
  • ActionSheetを表示してCommandを実行するBehavior

探せばありそうな気もしますし、一部Prismにも含まれていたりしますが、.NET Standardの学習もかねて作ってます。
まだ作ってる途中で全然テストとか書いてないけどw

動作感としてはこんな感じです。

f:id:nuitsjp:20170610193344g:plain

ちょっと見にくいけど選択した行が、下のSelectedItemに表示されていたりします。
まぁ、そこはBehaviorでやるほどではありませんが。
気になった方は良かったら続きをぜひ!

このサンプルではBehaviorを3種類の方法で利用しています。

  1. ItemTappedイベントを拾って、TapされたItemをCommandに引数で渡して実行するEventToCommandBehavior
  2. 登録ボタンを押下したら、DisplayAlertを表示して、OK・Cancelに応じたCommandを実行するDisplayAlertBehavior
  3. 登録処理完了後、VM側からのリクエストに応じて、完了メッセージを表示するDisplayAlertBehavior

DisplayAlertBehaviorが2個ありますが気にしない。

ItemTappedイベントを拾って、TapされたItemをCommandに引数で渡して実行するEventToCommandBehavior

XAMLはこんな感じです。

<ListView ItemsSource="{Binding Items}">
    <ListView.Behaviors>
        <behaviors:EventToCommandBehavior
            EventName="ItemTapped" 
            Command="{Binding TappedItemCommand}" 
            EventArgsPropertyPath="Item"/>
    </ListView.Behaviors>
</ListView>

でViewModelはこんな感じ

public ICommand TappedItemCommand => new Command<string>(item =>
{
    SelectedItem = item;
});

ポイントはEventToCommandBehaviorのEventArgsPropertyPathでItemを指定していること。
ItemTappedのイベントオブジェクトのItemプロパティだけをCommandに直接渡しています。
便利!(これはPrismに採用されていたアイディアを参考にさせてもらいました。)

登録ボタンを押下したら、DisplayAlertを表示して、OK・Cancelに応じたCommandを実行するDisplayAlertBehavior

XAMLはこんな感じ

<Button Grid.Row="2" Text="登録">
    <Button.Behaviors>
        <behaviors:DisplayAlertBehavior 
            EventName="Clicked" 
            Title="登録確認"
            Message="登録してもよろしいですか?"
            Accept="OK"
            Cancel="Cancel"
            AcceptCommand="{Binding RegistCommand}"/>
    </Button.Behaviors>
</Button>

今回は、OK押された時だけCommandを実行して、Cancel時は閉じるだけで良いので未指定です。
これで、OKが選択されるとRegistCommandが実行されます。

登録処理完了後、VM側からのリクエストに応じて、完了メッセージを表示するDisplayAlertBehavior

先ほどの登録ボタンのCommandは次のように実装しています。
ViewModel側です。

public ICommand RegistCommand => new Command(() =>
{
    NotifyCompletedRequest.Request();
});

public InteractionRequest NotifyCompletedRequest { get; } = new InteractionRequest();

RegistCommand の中でInteractionRequestクラスのRequestメソッドを呼んでいますね。
そしてそれに対応するXAMLがこう。

<behaviors:DisplayAlertBehavior 
    InteractionRequest="{Binding NotifyCompletedRequest}" 
    Title="登録結果"
    Message="登録が無事完了しました"
    Cancel="OK"/>

先のと同じDisplayAlertBehaviorなんですが、起動のキーはコントロールのイベントではなく、ViewModel側のInteractionRequest(プロパティ名はここではNotifyCompletedRequest)を起点にDisplayAlertを表示します。

便利じゃないですか?(ドヤ顔

ActionSheetBehaviorもあるよ

こんな感じに動くActionSheetを f:id:nuitsjp:20170610194656g:plain

こんな感じにXAMLで書いて、選択されたものに合わせてCommandを実行できます。

<Button Text="Display Action Sheet">
    <Button.Behaviors>
        <behaviors:DisplayActionSheetBehavior 
            EventName="Clicked" 
            InteractionRequest="{Binding DisplayActionSheetRequest}"
            Title="Alert Title" 
            Cancel="Cancel Sheet" 
            CancelCommand="{Binding ActionSheetCancelCommand}"
            Destruction="Destruction Sheet"
            DestructionCommand="{Binding ActionSheetDestructionCommand}">
            <behaviors:ActionSheetButton 
                Message="Action Sheet 1" 
                Command="{Binding ActionSheetButton1Command}"/>
            <behaviors:ActionSheetButton 
                Message="Action Sheet 2" 
                Command="{Binding ActionSheetButton2Command}"/>
        </behaviors:DisplayActionSheetBehavior>
    </Button.Behaviors>
</Button>

現在pre公開中です

てことで、すでにNuGetに公開しています。

www.nuget.org

リポジトリも公開してますよ~。

github.com

まだ試行錯誤して作りこんだだけで、未実装機能もあるし、テストコード書いていませんがこれから頑張ります。
完成したら良かったら使ってください!

てことで、今日はここまで! それではまた~。