.NET5のWPFにReactivePropertyをセットアップする

以前より圧倒的に簡単にセットアップできるようになっていて逆に混乱してしまったのでまとめておきます。

確認環境

  • VS2019(16.11.4)
  • .NET 5(C#9.0)
  • WPF プロジェクト作成済み(.NET, .NET F/W, .NET CoreどれでもOK)

セットアップ方法

Visual Studio のプロジェクトを右クリック > NuGet パッケージの管理から 「ReactiveProperty.WPF」 を導入する

もしくはパッケージマネージャーコンソールを開いて

ツール > NuGet パッケージ マネージャー > パッケージ マネージャー コンソール

以下コマンドを入力

NuGetのページ: https://www.nuget.org/packages/ReactiveProperty.WPF/

PM> Install-Package ReactiveProperty.WPF -Version 7.12.0

間接的に参照しているパッケージは自動的に解決してくれるので他は設定する必要ありません。

  • Microsoft.Xaml.Behaviors.dll
  • ReactiveProperty.dll
  • ReactiveProperty.Core.dll

UIイベントをCommandにバインドする

昔からUIのイベントをCommandににバインドする方法はありますが、数年前から書き方が変わってるので新しい方法を合わせて紹介します。

ViewModel側の定義

ViewModel 側には ReactiveCommand を以下のように宣言します。

ジェネリックで指定する型はイベント毎に型が違うのでイベントの引数とジェネリックの型が違うと実行時にキャストでエラーが出ます。MSDNのリファレンス見てイベントに応じた型を指定するようにしてください。

using Reactive.Bindings;

// ViewModelのコマンドの宣言
public class FolderViewModel : Bindable, IDisposable
{
    public ReactiveCommand<MouseEventArgs> ImageClickCommand { get; } = new();
}

// コマンドの処理内容を登録(コンストラクタとかから呼び出す)
private void SetupCommand()
{
    ImageClickCommand.Subscribe(e =>
    {
        // コマンドの処理内容
    });
}

XAML側の定義

XAML側はイベントトリガーをいつも通りに指定します。「xmlns:bh="http://schemas.microsoft.com/xaml/behaviors"」が「Microsoft.Xaml.Behaviors.dll」に対応した宣言です。

<UserControl x:Class="Samples.Sample"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:bh="http://schemas.microsoft.com/xaml/behaviors"
         xmlns:rp="clr-namespace:Reactive.Bindings.Interactivity;assembly=ReactiveProperty.WPF"
         xmlns:local="clr-namespace:Samples"
         mc:Ignorable="d"
         d:DataContext="{d:DesignInstance {x:Type local:FolderViewModel}}">

    <UserControl.DataContext>
        <local:FolderViewModel/>
    </UserControl.DataContext>

    <Grid>
        <Image Source="assets/icon.png">
            <!-- 以下を追加 -->
            <bh:Interaction.Triggers>
                <bh:EventTrigger EventName="MouseUp">
                    <rp:EventToReactiveCommand Command="{Binding ImageClickCommand}"/>
                </bh:EventTrigger>
            </bh:Interaction.Triggers>
        </Image>
    </Grid>
</UserControl>

以下を xmlns に追記

xmlns:bh="http://schemas.microsoft.com/xaml/behaviors"
xmlns:rp="clr-namespace:Reactive.Bindings.Interactivity;assembly=ReactiveProperty.WPF"

バインドしたいイベントの名前は IDE のインテリセンスには出てこないのでリファレンスを見るなどして正しい文字列を設定しましょう。

<bh:Interaction.Triggers>
    <bh:EventTrigger EventName="MouseUp">
        <rp:EventToReactiveCommand Command="{Binding ImageClickCommand}"/>
    </bh:EventTrigger>
</bh:Interaction.Triggers>

以上です。